<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Ethereum Improvement Proposals - Final</title>
    <subtitle>Ethereum Improvement Proposals (EIPs &amp; ERCs) describe standards for the Ethereum platform, such as core protocol changes and application-level standards.</subtitle>
    <link href="https://wg-eips.ritovision.com/status/final/atom.xml" rel="self" type="application/atom+xml"/>
    <link rel="alternate" type="text/html" href="https://wg-eips.ritovision.com/status/final/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-04-25T12:06:20+00:00</updated>
    <id>https://wg-eips.ritovision.com/status/final/atom.xml</id>
    <entry xml:lang="en">
        <title>Diamond Storage</title>
        <published>2025-10-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Nick Mudge</name><uri>https://github.com/mudgen</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/8042/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-8042-diamond-storage/25718" />
        

        <id>https://wg-eips.ritovision.com/8042/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:8042"
            label="ERC-8042" />
        

        
        

        
        <summary type="html">Define storage locations for structs using human-readable, meaningful strings.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/8042/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard formalizes the diamond storage pattern originally introduced by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;&quot;&gt;ERC-2535 Diamonds&lt;&#x2F;a&gt; and widely adopted across smart contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Though originally created for proxy contracts, diamond storage can be used to organize storage and data access within &lt;em&gt;any&lt;&#x2F;em&gt; smart contract.&lt;&#x2F;p&gt;
&lt;p&gt;Diamond storage defines the location of structs in contract storage using the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of human-readable identifiers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8042&#x2F;&quot;&gt;ERC-8042&lt;&#x2F;a&gt; standardizes this simple and production-proven approach, offering a lightweight alternative to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7201&#x2F;&quot;&gt;ERC-7201&lt;&#x2F;a&gt; for new and existing projects.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;On March 10, 2020, a change to the Solidity compiler introduced the ability to assign structs to any storage location. This enabled a new pattern for using separate areas of storage. The pattern became known as diamond storage, as it was first popularized by ERC-2535 Diamonds and has since been widely used.&lt;&#x2F;p&gt;
&lt;p&gt;Later, on June 20, 2023, ERC-7201 was introduced to standardize this general storage pattern. However, the formula that ERC-7201 proposed for generating storage locations differed from the one already established and in active use by diamond storage.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-8042 standardizes diamond storage for new projects and validates past diamond storage implementations.&lt;&#x2F;p&gt;
&lt;p&gt;While ERC-7201 defines a generalized mechanism for storage namespaces, ERC-8042 preserves the simplicity and backward compatibility of the diamond storage convention already deployed in production across many projects.&lt;&#x2F;p&gt;
&lt;p&gt;Developers may prefer diamond storage for its simplicity, restricted ASCII identifiers, and direct hash-based computation of storage locations.&lt;&#x2F;p&gt;
&lt;p&gt;This standard can be used by tools to find and access data within smart contract storage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Diamond storage defines where structs are located in contract storage.&lt;&#x2F;p&gt;
&lt;p&gt;A diamond storage identifier is defined as a string containing only printable ASCII characters. That is characters &lt;code&gt;0x20&lt;&#x2F;code&gt; through &lt;code&gt;0x7E&lt;&#x2F;code&gt; inclusive.&lt;&#x2F;p&gt;
&lt;p&gt;The location of a diamond storage struct is determined by the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of a diamond storage identifier.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recommendations&quot;&gt;Recommendations&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;h4 id=&quot;use-solidity-s-string-literals&quot;&gt;Use Solidity&#x27;s string literals&lt;&#x2F;h4&gt;
&lt;p&gt;A string literal is an ASCII string type that is literally written between quotes, for example: &lt;code&gt;&quot;this is a string literal&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is recommended to use Solidity&#x27;s string literals to create diamond storage identifiers because the Solidity compiler enforces that they only contain printable ASCII characters, characters &lt;code&gt;0x20&lt;&#x2F;code&gt; through &lt;code&gt;0x7E&lt;&#x2F;code&gt; inclusive. Hex (&lt;code&gt;\xNN&lt;&#x2F;code&gt;) and Unicode (&lt;code&gt;\uNNNN&lt;&#x2F;code&gt;) escape sequences should &lt;strong&gt;NOT&lt;&#x2F;strong&gt; be used in diamond storage identifiers.&lt;&#x2F;p&gt;
&lt;p&gt;It is recommended to use compile-time constant string literals. Here is an example:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;bytes32 constant STORAGE_POSITION = keccak256(&quot;myproject.erc721.registry&quot;);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;h4 id=&quot;use-unique-human-readable-meaningful-strings&quot;&gt;Use unique, human-readable, meaningful strings&lt;&#x2F;h4&gt;
&lt;p&gt;A human-readable string is a string that humans can normally read and understand, like &quot;Transaction successful&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;A meaningful string in this context is a string that appropriately names or describes a storage space, or uses a pattern to do so. For example, &lt;code&gt;&quot;myproject.erc721.registry&quot;&lt;&#x2F;code&gt; is a hierarchical pattern that specifies &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; related storage for a registry. The string &lt;code&gt;&quot;car.fish.piano.run&quot;&lt;&#x2F;code&gt; is not a meaningful string because it is random and does not appropriately name or describe something.&lt;&#x2F;p&gt;
&lt;p&gt;Diamond storage identifiers should be unique, human-readable, meaningful strings.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;h4 id=&quot;do-not-use-unicode-literals&quot;&gt;Do NOT use Unicode literals&lt;&#x2F;h4&gt;
&lt;p&gt;Unicode literals can contain invisible characters and other non-ASCII characters which violates the specification of this standard.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example of a Unicode literal in Solidity: &lt;code&gt;string memory a = unicode&quot;Hello 😃&quot;;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Unicode literals should &lt;strong&gt;NOT&lt;&#x2F;strong&gt; be used to create diamond storage identifiers.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;h4 id=&quot;do-not-use-the-space-0x20-character&quot;&gt;Do not use the space &lt;code&gt;0x20&lt;&#x2F;code&gt; character&lt;&#x2F;h4&gt;
&lt;p&gt;Including the space (&lt;code&gt;0x20&lt;&#x2F;code&gt;) character in diamond storage identifiers is not recommended, as it may interfere with tooling such as the NatSpec tag described next.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;erc-8042-natspec-tag&quot;&gt;ERC-8042 NatSpec tag&lt;&#x2F;h3&gt;
&lt;p&gt;ERC-7201 defines the NatSpec tag &lt;code&gt;@custom:storage-location &amp;lt;FORMULA_ID&amp;gt;:&amp;lt;NAMESPACE_ID&amp;gt;&lt;&#x2F;code&gt;, where &lt;code&gt;&amp;lt;FORMULA_ID&amp;gt;&lt;&#x2F;code&gt; identifies a formula used to compute the storage location of a struct based on the namespace id.&lt;&#x2F;p&gt;
&lt;p&gt;The formula identified by &lt;code&gt;erc8042&lt;&#x2F;code&gt; is defined as &lt;code&gt;erc8042(id: string literal) = keccak256(id)&lt;&#x2F;code&gt;. In Solidity, this corresponds to the expression &lt;code&gt;keccak256(id)&lt;&#x2F;code&gt;. When using this formula the annotation becomes &lt;code&gt;@custom:storage-location erc8042:&amp;lt;NAMESPACE_ID&amp;gt;&lt;&#x2F;code&gt;. For example, &lt;code&gt;@custom:storage-location erc8042:myproject.erc721.registry&lt;&#x2F;code&gt; annotates diamond storage with id &lt;code&gt;&quot;myproject.erc721.registry&quot;&lt;&#x2F;code&gt; rooted at &lt;code&gt;erc8042(&quot;myproject.erc721.registry&quot;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Proxy contracts and contracts that use &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; need a reliable and secure way to define, document, and manage separate areas of smart contract storage.&lt;&#x2F;p&gt;
&lt;p&gt;In March 2020, diamond storage established a way to do this and has been in use since then. However, diamond storage wasn&#x27;t formalized as a standard, which is important to clarify its mechanics, usage and precise specification.&lt;&#x2F;p&gt;
&lt;p&gt;In June 2023, ERC-7201 Namespaced Storage Layout standardized the general pattern but has looser restrictions on namespace ids and a more complicated formula for calculating storage locations. Some people may prefer using ERC-7201, especially if they may auto-generate machine-readable or random strings for their namespace ids.&lt;&#x2F;p&gt;
&lt;p&gt;Some people may prefer ERC-8042 Diamond Storage for its ASCII-enforced, human-readable, meaningful strings and simple calculation of storage locations.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-2535 Diamonds first introduced the pattern of distinct storage areas for smart contracts. ERC-7201 later standardized the idea. ERC-8042 standardizes the original, simpler diamond storage variant for new projects and legacy compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;Though originally created for proxy contracts, diamond storage can be used to organize storage and data access within &lt;em&gt;any&lt;&#x2F;em&gt; smart contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;comparing-erc-8042-and-erc-7201&quot;&gt;Comparing ERC-8042 and ERC-7201&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc-7201&quot;&gt;ERC-7201&lt;&#x2F;h4&gt;
&lt;p&gt;ERC-7201 applies a formula to a namespace id to generate a storage location. Per the ERC-7201 specification a namespace id is a string that should not contain any whitespace characters. A namespace id has no other restrictions. So a namespace id could be something meaningful like &lt;code&gt;mycompany.projectA.erc721&lt;&#x2F;code&gt; or it could be a series of random bytes, characters or words, etc.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-7201 uses the following formula, given in Solidity, to generate a storage location: &lt;code&gt;keccak256(abi.encode(uint256(keccak256(bytes(namespace id))) - 1)) &amp;amp; ~bytes32(uint256(0xff))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first part of the ERC-7201 formula &lt;code&gt;keccak256(abi.encode(uint256(keccak256(bytes(namespace id))) - 1))&lt;&#x2F;code&gt; ensures that the input bytes to the second call to &lt;code&gt;keccak256&lt;&#x2F;code&gt; will not match any input bytes used by Solidity&#x27;s types that also use &lt;code&gt;keccak256&lt;&#x2F;code&gt; to determine storage locations. This makes it possible to use any sequence of bytes for the namespace id.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The last part of ERC-7201, &lt;code&gt;&amp;amp; ~bytes32(uint256(0xff))&lt;&#x2F;code&gt; ensures that the final storage location is a multiple of 256 which may provide a gas optimization in the future.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;erc-8042&quot;&gt;ERC-8042&lt;&#x2F;h4&gt;
&lt;p&gt;ERC-8042 identifiers can only contain printable ASCII characters and recommends using Solidity&#x27;s string literals which enforces this constraint.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-8042 recommends human-readable, meaningful strings for diamond storage identifiers.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-8042 uses the following formula, given in Solidity, to generate a storage location: &lt;code&gt;keccak256(string literal)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Diamond storage as described by this standard has been in use for 5 years. This standard recognizes and standardizes all previous uses of diamond storage that conform to the specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;This is a simple example of a contract that uses diamond storage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC721Registry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A registry contract for tracking ERC721 contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *         Allows adding ERC721 contract addresses up to a configurable limit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-8042 Diamond Storage is used to organize and manage access to storage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Registry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts when the registry reaches its configured capacity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721RegistryFull&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Struct storage position defined by keccak256 hash &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         of diamond storage identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; STORAGE_POSITION &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;myproject.erc721.registry&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Storage layout for the ERC721 registry, following EIP-8042.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `erc721Contracts`: Dynamic array of registered ERC721 contract addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      - `registryLimit`: Maximum allowed entries.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @custom:storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-location erc8042:myproject.erc721.registry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721RegistryStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; erc721Contracts&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; registryLimit&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a pointer to the ERC721RegistryStorage struct in storage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Uses inline assembly to access the storage slot defined by STORAGE_POSITION.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ERC173Storage struct in storage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ERC721RegistryStorage&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; position &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; STORAGE_POSITION&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;      s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; position&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the maximum number of ERC721 contracts the registry can hold.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newLimit&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New registry capacity limit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setRegistryLimit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newLimit&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;    getStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;registryLimit &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _newLimit&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Adds an ERC721 contract address to the registry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts with `ERC721RegistryFull` if the registry is full.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _erc721Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the ERC721 contract to register.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addERC721Contract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _erc721Contract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&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&gt;    ERC721RegistryStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;erc721Contracts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;registryLimit&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721RegistryFull&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;erc721Contracts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_erc721Contract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a list of all registered ERC721 contract addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Array&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of registered ERC721 contract addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getERC721Registry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;erc721Contracts&lt;&#x2F;span&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;uniqueness-of-identifiers&quot;&gt;Uniqueness of identifiers&lt;&#x2F;h3&gt;
&lt;p&gt;Two independent contracts or libraries using the same human-readable string will map to the same storage slot. Developers must ensure that diamond storage identifiers are unique within a contract system to prevent unintentional data overlap or corruption. A common practice is to prefix identifiers with a project, organization, or standard name (for example, &lt;code&gt;&quot;myproject.erc721.registry&quot;&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ascii-input-restriction-to-prevent-storage-collisions&quot;&gt;ASCII Input Restriction to Prevent Storage Collisions&lt;&#x2F;h3&gt;
&lt;p&gt;To prevent storage collisions, diamond storage identifiers must consist only of printable ASCII characters, specifically the range &lt;code&gt;0x20&lt;&#x2F;code&gt; to &lt;code&gt;0x7E&lt;&#x2F;code&gt; inclusive. Identifiers must not include Unicode escape sequences (&lt;code&gt;\uNNNN&lt;&#x2F;code&gt;) or hexadecimal escape sequences (&lt;code&gt;\xNN&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Solidity’s storage slot encoding, as produced by &lt;code&gt;abi.encode(p)&lt;&#x2F;code&gt;, contains non-printable bytes, particularly null bytes (&lt;code&gt;0x00&lt;&#x2F;code&gt;), due to Solidity’s default storage layout and padding rules.&lt;&#x2F;p&gt;
&lt;p&gt;Allowing identifiers to include such bytes could enable a malicious developer to craft an identifier like &lt;code&gt;&quot;config\x00\x00...&quot;&lt;&#x2F;code&gt;. The bytes of such an identifier could collide with the storage encoded input of mappings, dynamic arrays, strings and bytes which use &lt;code&gt;keccak256&lt;&#x2F;code&gt; to compute storage locations. Such collisions could result in overwrites, corruption of contract state, or security vulnerabilities.&lt;&#x2F;p&gt;
&lt;p&gt;Restricting identifiers to printable ASCII removes this exploitable source of collision. While this restriction does not provide a mathematical guarantee that collisions are impossible — because, in theory, a sufficiently large storage layout position (&lt;code&gt;p&lt;&#x2F;code&gt;) could accidentally contain all printable ASCII bytes — the probability of this occurring is extremely small, and impractical.&lt;&#x2F;p&gt;
&lt;p&gt;By using human-readable, meaningful strings for identifiers, the practical likelihood of any collision is virtually zero, providing strong protection for the integrity and safety of contract storage.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;string-literals&quot;&gt;String Literals&lt;&#x2F;h3&gt;
&lt;p&gt;The specification recommends using string literals to create diamond storage identifiers because the Solidity compiler enforces that only printable ASCII characters are used. However, string literals should not use Unicode escape sequences (&lt;code&gt;\uNNNN&lt;&#x2F;code&gt; ) or hexadecimal escape sequences (&lt;code&gt;\xNN&lt;&#x2F;code&gt; ).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unicode-literals&quot;&gt;Unicode Literals&lt;&#x2F;h3&gt;
&lt;p&gt;Unicode literals (e.g. &lt;code&gt;unicode&quot;Hello 😃&quot;&lt;&#x2F;code&gt;) should not be used to create diamond storage identifiers because they can contain non-printable bytes and characters, and they can be used to obfuscate identifiers by using characters that look like other characters. For example, the Cyrillic character &lt;code&gt;а&lt;&#x2F;code&gt; (&lt;code&gt;\u0430&lt;&#x2F;code&gt;) looks identical to the ASCII character &lt;code&gt;a&lt;&#x2F;code&gt; (&lt;code&gt;\u0061&lt;&#x2F;code&gt;).” In addition Unicode has control characters that change the direction text is displayed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;keccak256-hash-collision-resistance&quot;&gt;&lt;code&gt;keccak256&lt;&#x2F;code&gt; Hash Collision Resistance&lt;&#x2F;h3&gt;
&lt;p&gt;The location of a diamond storage struct is determined by the output of the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash function. Some developers may wonder about the likelihood that a diamond storage struct lands at an address where it will accidentally overwrite existing storage data. The 256-bit address space of contract storage is so vast that the likelihood of data overlap is statistically improbable.&lt;&#x2F;p&gt;
&lt;p&gt;Solidity mappings, dynamic arrays, strings and bytes also use &lt;code&gt;keccak256&lt;&#x2F;code&gt; to determine their location in contract storage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Agent Coordination Framework</title>
        <published>2025-08-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Kwame Bryan</name><uri>https://github.com/KBryan</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/8001/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-8001-secure-intents-a-cryptographic-framework-for-autonomous-agent-coordination-draft-erc-8001/24989" />
        

        <id>https://wg-eips.ritovision.com/8001/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:8001"
            label="ERC-8001" />
        

        
        

        
        <summary type="html">Minimal, single-chain, multi-party agent coordination using EIP-712 attestations</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/8001/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;&quot;&gt;ERC-8001&lt;&#x2F;a&gt; defines a minimal, single-chain primitive for &lt;strong&gt;multi-party agent coordination&lt;&#x2F;strong&gt;. An initiator posts an intent and each participant provides a verifiable acceptance attestation. Once the required set of acceptances is present and fresh, the intent is executable. The standard specifies typed data, lifecycle, mandatory events, and verification rules compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2098&#x2F;&quot;&gt;EIP-2098&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5267&#x2F;&quot;&gt;EIP-5267&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;&quot;&gt;ERC-8001&lt;&#x2F;a&gt; omits privacy, reputation, threshold policies, bonding, and cross-chain semantics. Those are expected as optional modules that reference this specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Agents in DeFi&#x2F;MEV&#x2F;Web3 Gaming and Agentic Commerce often need to act together without a trusted coordinator. Existing intent standards (e.g., &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7521&#x2F;&quot;&gt;ERC-7521&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7683&#x2F;&quot;&gt;ERC-7683&lt;&#x2F;a&gt;) define single-initiator flows and do not specify multi-party agreement.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;&quot;&gt;ERC-8001&lt;&#x2F;a&gt; specifies the smallest on-chain primitive for that gap: an initiator&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; intent plus per-participant &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;EIP-1271&lt;&#x2F;a&gt; acceptances. The intent becomes executable only when the required set of acceptances is present and unexpired. Canonical (sorted-unique) participant lists and standard typed data provide replay safety and wallet compatibility. Privacy, thresholds, bonding, and cross-chain are left to modules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “SHOULD”, and “MAY” are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Implementations MUST expose the following canonical status codes for &lt;code&gt;getCoordinationStatus&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;status-codes&quot;&gt;Status Codes&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations MUST use the canonical enum defined below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Status&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Proposed&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Ready&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Executed&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Cancelled&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Expired&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;None&lt;&#x2F;code&gt; = default zero state (intent not found)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Proposed&lt;&#x2F;code&gt; = intent proposed, not all acceptances yet&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Ready&lt;&#x2F;code&gt; = all participants have accepted, intent executable&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Executed&lt;&#x2F;code&gt; = intent successfully executed&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Cancelled&lt;&#x2F;code&gt; = intent explicitly cancelled&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Expired&lt;&#x2F;code&gt; = intent expired before execution&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;This ERC specifies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A canonicalised EIP-712 domain for agent coordination,&lt;&#x2F;li&gt;
&lt;li&gt;Typed data structures (&lt;code&gt;AgentIntent&lt;&#x2F;code&gt;, &lt;code&gt;CoordinationPayload&lt;&#x2F;code&gt;, &lt;code&gt;AcceptanceAttestation&lt;&#x2F;code&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;Deterministic hashing rules,&lt;&#x2F;li&gt;
&lt;li&gt;A standard interface (&lt;code&gt;IAgentCoordination&lt;&#x2F;code&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;Lifecycle semantics (propose → accept → execute&#x2F;cancel),&lt;&#x2F;li&gt;
&lt;li&gt;Error surface and status codes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;eip-712-domain&quot;&gt;EIP-712 Domain&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations MUST use the following EIP-712 domain:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{name: &amp;quot;ERC-8001&amp;quot;, version: &amp;quot;1&amp;quot;, chainId, verifyingContract}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Implementations SHOULD expose the domain via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5267&#x2F;&quot;&gt;ERC-5267&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;primary-types&quot;&gt;Primary Types&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AgentIntent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; payloadHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256(CoordinationPayload)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt;  expiry&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unix seconds; MUST be &amp;gt; block.timestamp at propose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt;  nonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; per-agent nonce; MUST be &amp;gt; agentNonces[agentId]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; agentId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; initiator and signer of the intent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; coordinationType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; domain-specific type id, e.g. keccak256(&amp;quot;MEV_SANDWICH_COORD_V1&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; coordinationValue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; informational in Core; modules MAY bind value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; participants&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unique, ascending; MUST include agentId&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 class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CoordinationPayload&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; version&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; payload format id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; coordinationType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST equal AgentIntent.coordinationType&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt;   coordinationData&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; opaque to Core&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; conditionsHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; domain-specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; timestamp&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; creation time (informational)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt;   metadata&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; optional&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 class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AcceptanceAttestation&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getIntentHash(intent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; participant&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; signer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt;  nonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; optional in Core; see Nonces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt;  expiry&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; acceptance validity; MUST be &amp;gt; now at accept and execute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; conditionsHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; participant constraints&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt;   signature&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ECDSA (65 or 64 bytes) or ERC-1271&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;h3 id=&quot;typed-data-hashes&quot;&gt;Typed Data Hashes&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; AGENT_INTENT_TYPEHASH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-string&quot;&gt;  &amp;quot;AgentIntent(bytes32 payloadHash,uint64 expiry,uint64 nonce,address agentId,bytes32 coordinationType,uint256 coordinationValue,address[] participants)&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&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 class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ACCEPTANCE_TYPEHASH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Field names MUST exactly match the Solidity struct.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  &amp;quot;AcceptanceAttestation(bytes32 intentHash,address participant,uint64 nonce,uint64 expiry,bytes32 conditionsHash)&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&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; participants MUST be unique and strictly ascending by uint160(address).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _participantsHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ps&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ps&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _agentIntentStructHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AgentIntent&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      AGENT_INTENT_TYPEHASH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payloadHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;agentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;coordinationType&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;coordinationValue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;      _participantsHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;participants&lt;&#x2F;span&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;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Full EIP-712 digest for the initiator’s signature.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _agentIntentDigest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; domainSeparator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; AgentIntent&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;\x19\x01&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; domainSeparator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _agentIntentStructHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _acceptanceStructHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AcceptanceAttestation&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a.intentHash MUST be the AgentIntent struct hash, not the digest.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ACCEPTANCE_TYPEHASH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;intentHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;participant&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditionsHash&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&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _acceptanceDigest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; domainSeparator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; AcceptanceAttestation&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;\x19\x01&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; domainSeparator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _acceptanceStructHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Computation (normative):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;participantsHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;participants&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; sorted unique&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;intentStructHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  AGENT_INTENT_TYPEHASH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  payloadHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; agentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; coordinationType&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; coordinationValue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; participantsHash&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&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&gt;intentDigest &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;\x19\x01&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; domainSeparator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; intentStructHash&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Clarifications (normative):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getIntentHash(intent)&lt;&#x2F;code&gt; MUST return &lt;code&gt;intentStructHash&lt;&#x2F;code&gt; (struct hash), not the full digest.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;AcceptanceAttestation.intentHash&lt;&#x2F;code&gt; MUST be that struct hash.&lt;&#x2F;li&gt;
&lt;li&gt;Each acceptance is signed over its own EIP-712 digest that includes this field.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;participants&lt;&#x2F;code&gt; MUST be strictly ascending by &lt;code&gt;uint160(address)&lt;&#x2F;code&gt; and deduplicated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations &lt;strong&gt;MUST&lt;&#x2F;strong&gt; expose the following interface and events.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IAgentCoordination&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CoordinationProposed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proposer&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; coordinationType&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; participantCount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; coordinationValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CoordinationAccepted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; participant&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; acceptanceHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; acceptedCount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; requiredCount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CoordinationExecuted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; executor&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; gasUsed&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CoordinationCancelled&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; canceller&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; finalStatus&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; proposeCoordination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AgentIntent&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intent&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; CoordinationPayload&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payload&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptCoordination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; AcceptanceAttestation&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; attestation&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; allAccepted&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; executeCoordination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; CoordinationPayload&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payload&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; executionData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cancelCoordination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getCoordinationStatus&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Status&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; status&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proposer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; participants&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; acceptedBy&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expiry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRequiredAcceptances&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; intentHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getAgentNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; agent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;semantics&quot;&gt;Semantics&lt;&#x2F;h3&gt;
&lt;p&gt;The functions defined in this specification MUST exhibit the following externally observable behaviours.&lt;br &#x2F;&gt;
This standard does NOT prescribe storage layout, execution model, or internal mechanisms.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;proposecoordination&quot;&gt;&lt;code&gt;proposeCoordination&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;proposeCoordination&lt;&#x2F;code&gt; MUST revert if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the signature does not validate the supplied &lt;code&gt;AgentIntent&lt;&#x2F;code&gt; under the ERC-8001 EIP-712 domain;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;intent.expiry &amp;lt;= block.timestamp&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;intent.nonce&lt;&#x2F;code&gt; is not strictly greater than &lt;code&gt;getAgentNonce(intent.agentId)&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;participants&lt;&#x2F;code&gt; is not strictly ascending and unique;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;intent.agentId&lt;&#x2F;code&gt; is not included in the participants list.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If valid:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CoordinationProposed&lt;&#x2F;code&gt; MUST be emitted;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getCoordinationStatus&lt;&#x2F;code&gt; MUST report &lt;code&gt;Proposed&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getAgentNonce(intent.agentId)&lt;&#x2F;code&gt; MUST equal the supplied nonce;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getRequiredAcceptances(intentHash)&lt;&#x2F;code&gt; MUST equal the number of participants.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;acceptcoordination&quot;&gt;&lt;code&gt;acceptCoordination&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;acceptCoordination&lt;&#x2F;code&gt; MUST revert if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the intent does not exist or has expired;&lt;&#x2F;li&gt;
&lt;li&gt;the caller is not listed as a participant;&lt;&#x2F;li&gt;
&lt;li&gt;the participant has already accepted;&lt;&#x2F;li&gt;
&lt;li&gt;the attestation signature does not validate under the ERC-8001 domain;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;attestation.expiry &amp;lt;= block.timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If valid:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CoordinationAccepted&lt;&#x2F;code&gt; MUST be emitted;&lt;&#x2F;li&gt;
&lt;li&gt;the participant MUST appear in the &lt;code&gt;acceptedBy&lt;&#x2F;code&gt; list returned by &lt;code&gt;getCoordinationStatus&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;if all participants have accepted:
&lt;ul&gt;
&lt;li&gt;the function MUST return &lt;code&gt;true&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;status MUST be &lt;code&gt;Ready&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Otherwise the function MUST return &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;executecoordination&quot;&gt;&lt;code&gt;executeCoordination&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;executeCoordination&lt;&#x2F;code&gt; MUST revert if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the intent is not in &lt;code&gt;Ready&lt;&#x2F;code&gt; state;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;intent.expiry &amp;lt;= block.timestamp&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;any acceptance has expired;&lt;&#x2F;li&gt;
&lt;li&gt;the supplied payload does not hash to &lt;code&gt;payloadHash&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If valid:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the implementation MUST attempt execution of the behaviour represented by &lt;code&gt;executionData&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;the function MUST return &lt;code&gt;(success, result)&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CoordinationExecuted&lt;&#x2F;code&gt; MUST be emitted;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getCoordinationStatus&lt;&#x2F;code&gt; MUST report &lt;code&gt;Executed&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;cancelcoordination&quot;&gt;&lt;code&gt;cancelCoordination&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;If the intent has not expired, only the proposer MUST be permitted to cancel.&lt;&#x2F;li&gt;
&lt;li&gt;After expiry, any caller MUST be permitted to cancel.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On success:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CoordinationCancelled&lt;&#x2F;code&gt; MUST be emitted;&lt;&#x2F;li&gt;
&lt;li&gt;status MUST be &lt;code&gt;Cancelled&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;getcoordinationstatus&quot;&gt;&lt;code&gt;getCoordinationStatus&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;getCoordinationStatus(intentHash)&lt;&#x2F;code&gt; MUST return:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;None&lt;&#x2F;code&gt; if the intent does not exist;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Proposed&lt;&#x2F;code&gt; if not all participants have accepted and the intent has not expired;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Ready&lt;&#x2F;code&gt; if all participants have accepted and expiries have not elapsed;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Executed&lt;&#x2F;code&gt; if execution has occurred;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Cancelled&lt;&#x2F;code&gt; if cancellation has occurred;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Expired&lt;&#x2F;code&gt; if the intent has expired and was not executed or cancelled.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;nonces&quot;&gt;Nonces&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getAgentNonce(agent)&lt;&#x2F;code&gt; MUST increase for every valid new intent.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;proposeCoordination&lt;&#x2F;code&gt; MUST reject nonces not strictly greater than the stored nonce.&lt;&#x2F;li&gt;
&lt;li&gt;Acceptance-level nonces MAY be implemented; if so, they MUST be strictly monotonic per participant.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;errors&quot;&gt;Errors&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations SHOULD revert with descriptive custom errors (or equivalent revert strings) for the following baseline conditions, and MAY define additional errors for domain-specific modules (e.g. slashing, reputation, or privacy conditions):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Expired intent&lt;&#x2F;li&gt;
&lt;li&gt;Bad signature&lt;&#x2F;li&gt;
&lt;li&gt;Non-participant&lt;&#x2F;li&gt;
&lt;li&gt;Duplicate acceptance&lt;&#x2F;li&gt;
&lt;li&gt;Acceptance expired at execute&lt;&#x2F;li&gt;
&lt;li&gt;Payload hash mismatch&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_NotProposer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_ExpiredIntent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_ExpiredAcceptance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; participant&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_BadSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_NotParticipant&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_DuplicateAcceptance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_ParticipantsNotCanonical&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_NonceTooLow&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_PayloadHashMismatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC8001_NotReady&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&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;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Sorted participant lists remove hash malleability and allow off-chain deduplication.&lt;&#x2F;li&gt;
&lt;li&gt;Separation of intent and acceptance allows off-chain collation and a single on-chain check.&lt;&#x2F;li&gt;
&lt;li&gt;Keeping &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;&quot;&gt;ERC-8001&lt;&#x2F;a&gt; single-chain avoids coupling to bridge semantics and keeps the primitive audit-friendly.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet friendliness: EIP-712 arrays let signers see actual participant addresses.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;&quot;&gt;ERC-8001&lt;&#x2F;a&gt; introduces a new interface. It is compatible with EOA and contract wallets via ECDSA and ERC-1271. It does not modify existing standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A permissive reference implementation is provided in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8001&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;AgentCoordination.sol&quot;&gt;&lt;code&gt;contracts&#x2F;AgentCoordination.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. It uses a minimal ECDSA helper and supports ERC-1271 signers. It enforces participant canonicalisation, intent nonces, acceptance freshness, and all-participants policy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Replay&lt;&#x2F;strong&gt;: EIP-712 domain binding and monotonic nonces prevent cross-contract replay.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Malleability&lt;&#x2F;strong&gt;: Low-s enforcement and 64&#x2F;65-byte signature support are required.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Equivocation&lt;&#x2F;strong&gt;: A participant can sign conflicting intents. Mitigate with module-level slashing or reputation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Liveness&lt;&#x2F;strong&gt;: Enforce TTL on both intent and acceptances. Executors should ensure enough time remains.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MEV&lt;&#x2F;strong&gt;: If &lt;code&gt;coordinationData&lt;&#x2F;code&gt; reveals strategy, use a Privacy module with commit-reveal or encryption.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Purpose-Bound ERC-20 with Conditional Unlock</title>
        <published>2025-07-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Anushka Yadav</name><uri>https://github.com/64anushka</uri>
	</author>
	
	<author>
		<name>Akash Kothawade</name><uri>https://github.com/akash3927</uri>
	</author>
	
	<author>
		<name>Atishek Singh</name><uri>https://github.com/atisheksingh</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7994/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7994-purpose-bound-erc20-with-multi-condition-unlocking-extension-of-eip-7291/24945" />
        

        <id>https://wg-eips.ritovision.com/7994/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:7994"
            label="ERC-7994" />
        

        
        

        
        <summary type="html">Extends ERC-20 with programmable restrictions, enabling transfers based on multiple unlock conditions as defined in EIP-7291.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7994/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC extends the concept introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7291&#x2F;&quot;&gt;ERC-7291&lt;&#x2F;a&gt; by enabling &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;-compatible tokens to carry multi-condition unlocking constraints, combining temporal, identity, and usage restrictions into a programmable structure. It aims to support controlled disbursement of tokens where funds are only accessible under predefined, auditable, and verifiable conditions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-7291 introduced purpose-bound money by restricting how and where tokens can be spent. However, many real-world applications require multiple conditions to be satisfied simultaneously before tokens can be used. Examples include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Scholarships requiring the recipient to be KYC-verified, under 25 years of age, and registered at a university.&lt;&#x2F;li&gt;
&lt;li&gt;NGO aid to be used only for food and medicine, after a specific unlock date.&lt;&#x2F;li&gt;
&lt;li&gt;Payroll tokens that unlock monthly and only for whitelisted vendors (e.g., banks, healthcare providers).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal generalizes and formalizes such use cases by layering unlocking conditions on top of the ERC-20 standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;IPurposeBoundERC20&lt;&#x2F;code&gt; interface defines the standard for programmable token transfers that are conditional. Each transfer, referred to as a &lt;em&gt;purpose binding&lt;&#x2F;em&gt;, includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;recipient&lt;&#x2F;code&gt; and &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;A set of &lt;code&gt;UnlockCondition&lt;&#x2F;code&gt; objects, each consisting of a &lt;code&gt;conditionType&lt;&#x2F;code&gt; (like &lt;code&gt;&quot;TIME&quot;&lt;&#x2F;code&gt;, &lt;code&gt;&quot;KYC&quot;&lt;&#x2F;code&gt;, or &lt;code&gt;&quot;WHITELIST&quot;&lt;&#x2F;code&gt;) and &lt;code&gt;conditionData&lt;&#x2F;code&gt; used to evaluate the condition.&lt;&#x2F;li&gt;
&lt;li&gt;An optional &lt;code&gt;expiry&lt;&#x2F;code&gt; timestamp after which the transfer can no longer be claimed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The interface provides the following functions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bindPurpose(...)&lt;&#x2F;code&gt;: Locks a specified amount of tokens to a recipient with defined conditions.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claim(...)&lt;&#x2F;code&gt;: Allows the recipient to claim the tokens once all conditions are fulfilled.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;isUnlocked(...)&lt;&#x2F;code&gt;: Returns whether all associated conditions have been satisfied.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This enables flexible, composable transfer mechanisms for various use cases including compliance, grants, payroll, and more.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IPurposeBoundERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UnlockCondition&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; conditionType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; e.g., &amp;quot;TIME&amp;quot;, &amp;quot;KYC&amp;quot;, &amp;quot;WHITELIST&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt; conditionData&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; e.g., timestamp, Merkle root, etc.&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bindPurpose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        UnlockCondition&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; conditions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expiry&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; claim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isUnlocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Flexibility: Conditions are modular and extensible.&lt;&#x2F;p&gt;
&lt;p&gt;Composability: Can be integrated into DAOs, payroll, education, and compliance tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Security: Off-chain verification (e.g., KYC) backed by on-chain proofs (e.g., Merkle roots).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reference Implementation - Purpose-Bound ERC20 with Multi-Condition Unlocking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Implements IPurposeBoundERC20 with conditionType mapping to on-chain checkers.&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IPurposeBoundERC20.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for pluggable condition checker contracts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IConditionChecker&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isConditionMet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; conditionData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; PurposeBoundERC20 Implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PurposeBoundERC20&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IPurposeBoundERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StoredBinding&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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&gt;        UnlockCondition&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; conditions&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; claimed&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maps conditionType → on-chain checker contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; conditionResolvers&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maps bindingId → locked transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; StoredBinding&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; boundTransfers&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PurposeBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Claimed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;name_, symbol_) &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1_000_000&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ether&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; for demo purposes&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Admin can register or update condition checkers for condition types&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setConditionResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; conditionType&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; checker&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For demo purposes: public function. In production: onlyOwner or AccessControl.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        conditionResolvers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;conditionType&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; checker&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IPurposeBoundERC20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bindPurpose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        UnlockCondition&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; conditions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expiry&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;recipient &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid recipient&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid amount&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bindingId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conditions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        StoredBinding &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; stored &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; boundTransfers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;stored&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Binding exists&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; conditions&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            stored&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditions&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;conditions&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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&gt;        stored&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;recipient &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        stored&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        stored&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiry &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PurposeBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IPurposeBoundERC20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isUnlocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;        StoredBinding &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; binding &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; boundTransfers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;claimed&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiry &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditions&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            UnlockCondition &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; cond &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditions&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span&gt; checker &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; conditionResolvers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;cond&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditionType&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;checker &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Checker not set&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IConditionChecker&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;checker&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isConditionMet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conditionData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IPurposeBoundERC20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; claim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bindingId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        StoredBinding &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; binding &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; boundTransfers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not recipient&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;claimed&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Already claimed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isUnlocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Conditions not met&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;claimed &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Claimed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bindingId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; binding&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;recipient&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example of Time-Based Condition Checker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TimeConditionChecker&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IConditionChecker&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isConditionMet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; conditionData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; unlockTime &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;conditionData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; unlockTime&lt;&#x2F;span&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Condition-checking mechanisms (e.g., Merkle roots, timestamps) must be secure against tampering.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;claim()&lt;&#x2F;code&gt; function must ensure atomic verification of all conditions.&lt;&#x2F;p&gt;
&lt;p&gt;Replay attacks must be mitigated using unique binding IDs and expiration fields.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Precompile for secp256r1 Curve Support</title>
        <published>2025-05-27T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Carl Beekhuizen</name><uri>https://github.com/carlbeek</uri>
	</author>
	
	<author>
		<name>Ulaş Erdoğan</name><uri>https://github.com/ulerdogan</uri>
	</author>
	
	<author>
		<name>Doğan Alpaslan</name><uri>https://github.com/doganalpaslan</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7951/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7951-precompile-for-secp256r1-curve-support/24360" />
        

        <id>https://wg-eips.ritovision.com/7951/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7951"
            label="EIP-7951" />
        

        
        

        
        <summary type="html">Add precompiled contract for secp256r1 ECDSA signature verification with proper security checks</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7951/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add functionality to efficiently perform ECDSA signature verification over the secp256r1 elliptic curve (also known as P-256 or prime256v1). This precompile enables native support for signatures generated by modern secure hardware including Apple Secure Enclave, Android Keystore, and FIDO2&#x2F;WebAuthn devices.&lt;&#x2F;p&gt;
&lt;p&gt;This specification addresses critical security issues discovered in RIP-7212 while maintaining full interface compatibility with existing Layer 2 implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The secp256r1 elliptic curve is a NIST-standardized curve widely supported in modern secure hardware and authentication systems. Adding native support for secp256r1 signature verification to Ethereum enables several important use cases that are currently impossible or prohibitively expensive.&lt;&#x2F;p&gt;
&lt;p&gt;Modern secure hardware devices, including Apple Secure Enclave, Android Keystore, HSMs, TEEs, and FIDO2&#x2F;WebAuthn authenticators, use secp256r1 for key storage and signing operations. Native secp256r1 support enables sophisticated account abstraction patterns like device-native signing, multi-factor authentication, and simplified key management - ultimately reducing friction for mainstream adoption through familiar authentication flows.&lt;&#x2F;p&gt;
&lt;p&gt;The secp256r1 curve is already widely supported across blockchain networks and protocols, including Layer 2 networks, enterprise blockchains, and interoperability protocols. This broad compatibility enables seamless integration with existing infrastructure while maintaining security through hardware-backed signing capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP supersedes RIP-7212 by implementing the same functionality with the same interface, but without the vulnerability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;precompile&quot;&gt;Precompile&lt;&#x2F;h3&gt;
&lt;p&gt;We introduce &lt;code&gt;P256VERIFY&lt;&#x2F;code&gt; a precompile at the address &lt;code&gt;0x100&lt;&#x2F;code&gt; which performs ECDSA signature verification over the secp256r1 curve with a gas cost of &lt;code&gt;6900&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h3 id=&quot;curve-parameters&quot;&gt;Curve Parameters&lt;&#x2F;h3&gt;
&lt;p&gt;The secp256r1 curve is fully defined by the following set of parameters:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Base field modulus = p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Curve equation: y^2 = x^3 + ax + b (mod p)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Curve coefficient a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Curve coefficient b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Base point G:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Subgroup order = n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cofactor = h = 0x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These parameters are standardized by NIST in SP 800-186&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fields-and-groups&quot;&gt;Fields and Groups&lt;&#x2F;h3&gt;
&lt;p&gt;The field Fp is defined as the finite field of size &lt;code&gt;p&lt;&#x2F;code&gt; with elements represented as integers between 0 and p-1 (both inclusive).&lt;&#x2F;p&gt;
&lt;p&gt;The group G is defined as a set of Fp pairs (points) &lt;code&gt;(x,y)&lt;&#x2F;code&gt; such that either &lt;code&gt;(x,y)&lt;&#x2F;code&gt; is &lt;code&gt;(0,0)&lt;&#x2F;code&gt; (representing the point at infinity) or &lt;code&gt;x,y&lt;&#x2F;code&gt; satisfy the curve equation &lt;code&gt;y^2 = x^3 + ax + b (mod p)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;points-and-encoding&quot;&gt;Points and Encoding&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;field-elements-encoding&quot;&gt;Field Elements Encoding&lt;&#x2F;h4&gt;
&lt;p&gt;A base field element (Fp) is encoded as &lt;code&gt;32&lt;&#x2F;code&gt; bytes by performing BigEndian encoding of the corresponding (unsigned) integer. The corresponding integer &lt;strong&gt;must&lt;&#x2F;strong&gt; be less than the field modulus &lt;code&gt;p&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;encoding-of-points-in-g&quot;&gt;Encoding of Points in G&lt;&#x2F;h4&gt;
&lt;p&gt;Points in G are encoded as byte concatenation of the respective encodings of the &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; coordinates. Total encoding length for a G point is thus &lt;code&gt;64&lt;&#x2F;code&gt; bytes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;point-of-infinity-encoding&quot;&gt;Point of Infinity Encoding&lt;&#x2F;h4&gt;
&lt;p&gt;For secp256r1, the point with coordinates &lt;code&gt;(0, 0)&lt;&#x2F;code&gt; (zeroes in Fp) is &lt;em&gt;not&lt;&#x2F;em&gt; on the curve, so a sequence of &lt;code&gt;64&lt;&#x2F;code&gt; zero bytes is used by convention to encode the point of infinity.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;encoding-of-scalars&quot;&gt;Encoding of Scalars&lt;&#x2F;h4&gt;
&lt;p&gt;A scalar is encoded as &lt;code&gt;32&lt;&#x2F;code&gt; bytes by performing BigEndian encoding of the corresponding (unsigned) integer. The corresponding integer is &lt;strong&gt;not&lt;&#x2F;strong&gt; required to be less than or equal to the subgroup order &lt;code&gt;n&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;behavior-on-invalid-inputs&quot;&gt;Behavior on Invalid Inputs&lt;&#x2F;h4&gt;
&lt;p&gt;On inputs that cannot be valid encodings of field elements or points, the precompile &lt;em&gt;must&lt;&#x2F;em&gt; return `` (failure).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;abi-for-p256verify-operation&quot;&gt;ABI for &lt;code&gt;P256VERIFY&lt;&#x2F;code&gt; Operation&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;input&quot;&gt;Input&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;P256VERIFY&lt;&#x2F;code&gt; call expects &lt;code&gt;160&lt;&#x2F;code&gt; bytes as input that is interpreted as byte concatenation of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;32&lt;&#x2F;code&gt; bytes: message hash &lt;code&gt;h&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;32&lt;&#x2F;code&gt; bytes: signature component &lt;code&gt;r&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;32&lt;&#x2F;code&gt; bytes: signature component &lt;code&gt;s&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;32&lt;&#x2F;code&gt; bytes: public key x-coordinate &lt;code&gt;qx&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;32&lt;&#x2F;code&gt; bytes: public key y-coordinate &lt;code&gt;qy&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;output&quot;&gt;Output&lt;&#x2F;h4&gt;
&lt;p&gt;Output is &lt;code&gt;32&lt;&#x2F;code&gt; bytes on successful verification and &lt;code&gt;0&lt;&#x2F;code&gt; bytes on failure:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;code&gt; for valid signatures&lt;&#x2F;li&gt;
&lt;li&gt;`` for invalid signatures or invalid inputs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;input-validation&quot;&gt;Input Validation&lt;&#x2F;h4&gt;
&lt;p&gt;The precompile MUST perform the following validation checks and return `` (failure) if any check fails:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Input length&lt;&#x2F;strong&gt;: Input MUST be exactly &lt;code&gt;160&lt;&#x2F;code&gt; bytes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Signature component bounds&lt;&#x2F;strong&gt;: Both &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; MUST satisfy &lt;code&gt;0 &amp;lt; r &amp;lt; n&lt;&#x2F;code&gt; and &lt;code&gt;0 &amp;lt; s &amp;lt; n&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Public key bounds&lt;&#x2F;strong&gt;: Both &lt;code&gt;qx&lt;&#x2F;code&gt; and &lt;code&gt;qy&lt;&#x2F;code&gt; MUST satisfy &lt;code&gt;0 ≤ qx &amp;lt; p&lt;&#x2F;code&gt; and &lt;code&gt;0 ≤ qy &amp;lt; p&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Point validity&lt;&#x2F;strong&gt;: The point &lt;code&gt;(qx, qy)&lt;&#x2F;code&gt; MUST satisfy the curve equation &lt;code&gt;qy^2 ≡ qx^3 + a*qx + b (mod p)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Point not at infinity&lt;&#x2F;strong&gt;: The point &lt;code&gt;(qx, qy)&lt;&#x2F;code&gt; MUST NOT be the point at infinity (represented as &lt;code&gt;(0, 0)&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;signature-verification-algorithm&quot;&gt;Signature Verification Algorithm&lt;&#x2F;h4&gt;
&lt;p&gt;The verification algorithm follows these steps:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Input validation (as specified above)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if input_length != 160:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if not (0 &amp;lt; r &amp;lt; n and 0 &amp;lt; s &amp;lt; n):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if not (0 ≤ qx &amp;lt; p and 0 ≤ qy &amp;lt; p):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if qy^2 ≢ qx^3 + a*qx + b (mod p):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if (qx, qy) == (0, 0):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return&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;# Signature verification&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s1 = s^(-1) (mod n)&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;# Recover the random point used during signing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;R&amp;#39; = (h * s1) * G + (r * s1) * (qx, qy)&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;# Check for point at infinity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if R&amp;#39; is the point at infinity:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return&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;# Extract x-coordinate from r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;r&amp;#39; = R&amp;#39;.x&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;# Compare with modular reduction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if r&amp;#39; ≡ r (mod n):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;else:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;error-cases&quot;&gt;Error Cases&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Invalid input length (not exactly 160 bytes)&lt;&#x2F;li&gt;
&lt;li&gt;Invalid field element encoding (≥ field modulus)&lt;&#x2F;li&gt;
&lt;li&gt;Invalid signature component bounds (r or s not in range (0, n))&lt;&#x2F;li&gt;
&lt;li&gt;Invalid public key (point at infinity or not on curve)&lt;&#x2F;li&gt;
&lt;li&gt;Signature verification failure&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;gas-schedule&quot;&gt;Gas Schedule&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;p256verify-operation&quot;&gt;&lt;code&gt;P256VERIFY&lt;&#x2F;code&gt; operation&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;6900&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;p&gt;This cost is based on benchmarking against the existing &lt;code&gt;ECRECOVER&lt;&#x2F;code&gt; precompile (&lt;code&gt;3000&lt;&#x2F;code&gt; gas). During benchmarks we found that the actual cost of R1 verification was significantly slower than the &lt;code&gt;ECRECOVER&lt;&#x2F;code&gt; precompile and the decision was made to increase the gas cost to &lt;code&gt;6900&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;gas-burning-on-error&quot;&gt;Gas Burning on Error&lt;&#x2F;h4&gt;
&lt;p&gt;The precompile MUST NOT revert under any circumstances. Invalid inputs or verification failures MUST return `` and consume the same amount of gas had verification succeeded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;security-fixes&quot;&gt;Security Fixes&lt;&#x2F;h3&gt;
&lt;p&gt;This specification addresses two critical vulnerabilities in RIP-7212:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Point-at-infinity check&lt;&#x2F;strong&gt;: The original RIP-7212 failed to check if the recovered point R&#x27; is the point at infinity. This could lead to non-deterministic behavior where the verification result depends on the underlying implementation&#x27;s handling of infinity points, potentially causing consensus failures.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modular comparison&lt;&#x2F;strong&gt;: The original comparison &lt;code&gt;r&#x27; == r&lt;&#x2F;code&gt; should be &lt;code&gt;r&#x27; ≡ r (mod n)&lt;&#x2F;code&gt; to handle cases where the x-coordinate of R&#x27; exceeds the curve order n. This ensures mathematically correct verification according to ECDSA standards.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;verification-vs-recovery&quot;&gt;Verification vs Recovery&lt;&#x2F;h3&gt;
&lt;p&gt;This specification uses signature verification rather than public key recovery (like &lt;code&gt;ECRECOVER&lt;&#x2F;code&gt;) because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Most secp256r1 implementations in hardware and software verify signatures directly&lt;&#x2F;li&gt;
&lt;li&gt;The NIST FIPS 186-5 standard[^2] specifies verification, not recovery&lt;&#x2F;li&gt;
&lt;li&gt;Verification is more efficient than recovery for this curve&lt;&#x2F;li&gt;
&lt;li&gt;Existing hardware implementations provide verification interfaces&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;gas-cost-justification&quot;&gt;Gas Cost Justification&lt;&#x2F;h3&gt;
&lt;p&gt;The 6900 gas cost does not maintain compatibility with L2s, but it matches closer the benchmarks of actual implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP maintains full interface compatibility with RIP-7212 implementations deployed on Layer 2 networks. The same contract bytecode that works with RIP-7212 will work with this specification.&lt;&#x2F;p&gt;
&lt;p&gt;The security fixes are transparent to correctly implemented callers - they only affect edge cases that should have failed verification anyway. No existing valid use cases are broken.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface-compatibility&quot;&gt;Interface Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;The precompile maintains a similar interface as RIP-7212 to ensure compatibility with existing Layer 2 deployments:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Same address: &lt;code&gt;0x100&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Same input format: 160 bytes&lt;&#x2F;li&gt;
&lt;li&gt;Same output format: 32 bytes&lt;&#x2F;li&gt;
&lt;li&gt;Different gas cost: 3450 gas vs 6900 gas&lt;&#x2F;li&gt;
&lt;li&gt;Same return values&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;A set of test vectors for verifying implementations is located in a separate &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7951&#x2F;.&#x2F;assets&#x2F;test-vectors.json&quot;&gt;file&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation is not supplied due to the ubiquity of secp256r1, if however a reference is needed, the NIST specification in FIPS 186-5[^2]&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;cryptographic-security&quot;&gt;Cryptographic Security&lt;&#x2F;h3&gt;
&lt;p&gt;The secp256r1 curve provides approximately 128 bits of security, equivalent to secp256k1 already in use in Ethereum. The curve parameters are standardized by NIST SP 800-186&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-2&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and have undergone extensive cryptographic analysis by the wider cryptographic community in addition to this curve being deployed to several L2s in the form of RIP-7212.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;malleability&quot;&gt;Malleability&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike secp256k1 ECDSA signatures, secp256r1 ECDSA signatures are not required to be non-malleable per NIST FIPS 186-5 standard [^2]. Applications requiring non-malleability should implement additional checks at the application layer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;side-channel-resistance&quot;&gt;Side-Channel Resistance&lt;&#x2F;h3&gt;
&lt;p&gt;We explicitly state that this precompile &lt;strong&gt;IS NOT REQUIRED&lt;&#x2F;strong&gt; to perform all the operations using constant time algorithms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Chen, L., Moody, D., Regenscheid, A., Randall, K., &amp;amp; Robinson, A. (2023). &lt;span style=&quot;font-style: italic;&quot;&gt;Recommendations for Discrete Logarithm-based Cryptography: Elliptic Curve Domain Parameters&lt;&#x2F;span&gt; (Nos. 800–186). National Institute of Standards and Technology. https:&#x2F;&#x2F;doi.org&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.6028&#x2F;NIST.SP.800-186&quot;&gt;10.6028&#x2F;NIST.SP.800-186&lt;&#x2F;a&gt;[^2]: National Institute of Standards and Technology. (2023). &lt;span style=&quot;font-style: italic;&quot;&gt;Digital Signature Standard (DSS)&lt;&#x2F;span&gt; (Nos. 186–5). National Institute of Standards and Technology. https:&#x2F;&#x2F;doi.org&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.6028&#x2F;NIST.FIPS.186-5&quot;&gt;10.6028&#x2F;NIST.FIPS.186-5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Encode chain id with transaction hash</title>
        <published>2025-05-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Lauri Peltonen</name><uri>https://github.com/microbecode</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7950/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/a-new-standard-for-encoding-chain-id-transaction-hash/23782" />
        

        <id>https://wg-eips.ritovision.com/7950/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7950"
            label="ERC-7950" />
        

        
        

        
        <summary type="html">Encode a chain ID and transaction hash into a unique string format</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7950/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard proposes a way to encode the combination of a chain ID and a transaction hash into one string.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Looking up a transaction by its hash always requires the context of the chain - a transaction hash alone is not enough to identify the used chain. If the chain information is included in the string itself, finding the right chain for the transaction is easy.&lt;&#x2F;p&gt;
&lt;p&gt;Such strings can then be used, for example, in a forwarder service that forwards to the correct blockchain explorer.&lt;&#x2F;p&gt;
&lt;p&gt;The chain id is included in some object formats, such as the transaction object inside the blockchain itself, but that object has a lot of unneeded data for our purposes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The encoded string has three components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A chain ID, denoted as &lt;code&gt;chainId&lt;&#x2F;code&gt;. The used chain id MUST be based on &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; and the chain ID repository stated in that EIP.&lt;&#x2F;li&gt;
&lt;li&gt;A transaction hash, denoted as &lt;code&gt;txHash&lt;&#x2F;code&gt;. The hash MUST include the &lt;code&gt;0x&lt;&#x2F;code&gt; prefix.&lt;&#x2F;li&gt;
&lt;li&gt;A static string &lt;code&gt;tx&lt;&#x2F;code&gt;, acting as a type identifier.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The syntax is: &lt;code&gt;chainId:txHash:tx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An example for a transaction with hash &lt;code&gt;0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef&lt;&#x2F;code&gt; that was issued on chain ID &lt;code&gt;1&lt;&#x2F;code&gt; is: &lt;code&gt;1:0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef:tx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;All of the characters are case-insensitive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The chain ID is the most important detail when routing queries based on this standard and is therefore the first element in the string. The transaction hash is the second most important element.&lt;&#x2F;p&gt;
&lt;p&gt;The suffix &lt;code&gt;tx&lt;&#x2F;code&gt; is used to differentiate from, for example, addresses. Without the &lt;code&gt;tx&lt;&#x2F;code&gt; it would remain unclear whether an encoded string refers to an address, a transaction hash or something else.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce direct security risks. It is up to the external service providers (such as wallet developers and blockchain explorers) to decide how and if they want to incorporate this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Count leading zeros (CLZ) opcode</title>
        <published>2025-04-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vectorized</name><uri>https://github.com/Vectorized</uri>
	</author>
	
	<author>
		<name>Georgios Konstantopoulos</name><uri>https://github.com/gakonst</uri>
	</author>
	
	<author>
		<name>Jochem Brouwer</name><uri>https://github.com/jochem-brouwer</uri>
	</author>
	
	<author>
		<name>Ben Adams</name><uri>https://github.com/benaadams</uri>
	</author>
	
	<author>
		<name>Giulio Rebuffo</name><uri>https://github.com/Giulio2002</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7939/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/create-a-new-opcode-for-counting-leading-zeros-clz/10805" />
        

        <id>https://wg-eips.ritovision.com/7939/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7939"
            label="EIP-7939" />
        

        
        

        
        <summary type="html">Opcode to count the number of leading zero bits in a 256-bit word</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7939/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce a new opcode, &lt;code&gt;CLZ(x)&lt;&#x2F;code&gt;, which pops &lt;code&gt;x&lt;&#x2F;code&gt; from the stack and pushes the number of leading zero bits in &lt;code&gt;x&lt;&#x2F;code&gt; to the stack. If &lt;code&gt;x&lt;&#x2F;code&gt; is zero, pushes 256.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Count leading zeros (CLZ) is a native opcode in many processor architectures (even in RISC architectures like ARM).&lt;&#x2F;p&gt;
&lt;p&gt;It is a basic building block used in math operations, byte operations, compression algorithms, data structures:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;lnWad&lt;&#x2F;li&gt;
&lt;li&gt;powWad&lt;&#x2F;li&gt;
&lt;li&gt;lambertW0Wad&lt;&#x2F;li&gt;
&lt;li&gt;sqrt&lt;&#x2F;li&gt;
&lt;li&gt;cbrt&lt;&#x2F;li&gt;
&lt;li&gt;byte string comparisons&lt;&#x2F;li&gt;
&lt;li&gt;generalized calldata compression&#x2F;decompression&lt;&#x2F;li&gt;
&lt;li&gt;bitmaps (for finding the next&#x2F;previous set&#x2F;unset bit)&lt;&#x2F;li&gt;
&lt;li&gt;post quantum signature schemes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Adding a &lt;code&gt;CLZ&lt;&#x2F;code&gt; opcode will:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lead to cheaper compute.&lt;&#x2F;li&gt;
&lt;li&gt;Lead to cheaper ZK proving costs. The fastest known Solidity implementation uses several dynamic bitwise right shifts &lt;code&gt;shr&lt;&#x2F;code&gt;, which are very expensive to prove. In SP1 rv32im, a 32-bit right shift costs 1.6x more than a 32-bit mul.&lt;&#x2F;li&gt;
&lt;li&gt;Lead to smaller bytecode size. The fastest known Solidity implementation contains several large constants and is often inlined for performance.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;A new opcode is introduced: &lt;code&gt;CLZ&lt;&#x2F;code&gt; (&lt;code&gt;0x1e&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Pops 1 value from the stack.&lt;&#x2F;li&gt;
&lt;li&gt;Pushes a value to the stack, according to the following code:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Count leading zeros.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the number of zeros preceding the most significant one bit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If `x` is zero, returns 256.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is the fastest known `CLZ` implementation in Solidity and uses about 184 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @solidity memory-safe-assembly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; lt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; lt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; lt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; lt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; lt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; forgefmt: disable-next-item&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;xor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; byte&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;and&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x1f&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x8421084210842108cc6318c6db6d54be&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;            0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iszero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&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&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;Or in Python,&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Returns the number of zeros preceding the most significant one bit.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;clz is undefined for negative numbers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;clz is undefined for numbers larger than 2**256 - 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Convert to binary string and remove any &amp;#39;0b&amp;#39; prefix.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bin_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bin_str&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;Or in C++,&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    uint32_t&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;FFFF0000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;FF000000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;  x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;F0000000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;  x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;C0000000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;  x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;80000000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `x` is a uint256 bit number represented with 8 uint32 limbs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This implementation is optimized for SP1 proving via rv32im.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For regular compute, it performs similarly to `ADD`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 96&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 160&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 192&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 224&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; clz&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 256&lt;&#x2F;span&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 cost of the opcode is 5, matching MUL (raised from 3 to avoid under-pricing DoS risk).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-special-0-case&quot;&gt;The special 0 case&lt;&#x2F;h3&gt;
&lt;p&gt;256 is the smallest number after 255. Returning a small number allows the result to be compared with minimal additional bytecode.&lt;&#x2F;p&gt;
&lt;p&gt;For byte scanning operations, one can get the number of bytes to be skipped for a zero word by simply computing &lt;code&gt;256 &amp;gt;&amp;gt; 3&lt;&#x2F;code&gt;, which gives 32.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preference-over-ctz-count-trailing-zeros&quot;&gt;Preference over &lt;code&gt;CTZ&lt;&#x2F;code&gt; (count trailing zeros)&lt;&#x2F;h3&gt;
&lt;p&gt;Computing the least significant bit can be easily implemented with &lt;code&gt;CLZ&lt;&#x2F;code&gt; by isolating the smallest bit via &lt;code&gt;x &amp;amp; -x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, it is not possible to implement &lt;code&gt;CLZ&lt;&#x2F;code&gt; with &lt;code&gt;CTZ&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-cost&quot;&gt;Gas cost&lt;&#x2F;h3&gt;
&lt;p&gt;We have benchmarked the &lt;code&gt;CLZ&lt;&#x2F;code&gt; implementation against the &lt;code&gt;ADD&lt;&#x2F;code&gt; implementation in the intx library. &lt;code&gt;CLZ&lt;&#x2F;code&gt; uses approximately the same amount of compute cycles as &lt;code&gt;ADD&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The SP1 rv32im optimized variant uses less compute cycles than &lt;code&gt;ADD&lt;&#x2F;code&gt;, in the average and worst cases.&lt;&#x2F;p&gt;
&lt;p&gt;In SP1 rv32im, a 256-bit &lt;code&gt;CLZ&lt;&#x2F;code&gt; is cheaper to prove than &lt;code&gt;ADD&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is a new opcode not present prior.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0x000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x0000000000000000000000000000000000000000000000000000000000000100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0x4000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH32 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CLZ&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;0x00000000000000000000000000000000000000000000000000000000000000ff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;CLZ&lt;&#x2F;code&gt; is a stateless opcode that has a low worst-case constant cost in memory usage, compute and proving costs. It is therefore safe from being exploited for denial of service attacks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Set default gas limit to 60M</title>
        <published>2025-04-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Sophia Gold</name><uri>https://github.com/sophia-gold</uri>
	</author>
	
	<author>
		<name>Parithosh Jayanthi</name><uri>https://github.com/parithoshj</uri>
	</author>
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	<author>
		<name>Carl Beekhuizen</name><uri>https://github.com/CarlBeek</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	<author>
		<name>Josh Rudolph</name><uri>https://github.com/jrudolph</uri>
	</author>
	
	<author>
		<name>Giulio Rebuffo</name><uri>https://github.com/Giulio2002</uri>
	</author>
	
	<author>
		<name>Storm Slivkoff</name><uri>https://github.com/sslivkoff</uri>
	</author>
	
	<author>
		<name>Kamil Chodoła</name><uri>https://github.com/kamilchodola</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7935/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7935-set-default-gas-limit-to-60m/23789" />
        

        <id>https://wg-eips.ritovision.com/7935/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        

        
        <category
            term="tag:eip:7935"
            label="EIP-7935" />
        

        
        

        
        <summary type="html">Recommend a new gas limit value for Fusaka and update execution layer client default configs</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7935/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The gas limit on mainnet is currently 36M. This should be significantly increased to 60M by the time Fusaka is released by execution layer clients updating their default configurations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There is currently great interest in scaling L1 execution. This can likely be done to some extent without implementing any new features. However, it requires guidance from EL devs as we expect to find bugs in clients at higher gas limits than currently used on mainnet. This will require time from client developers both to test and to fix any bugs that arise, therefore it makes sense to include as an EIP in a hard fork to commit to this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Execution layer clients have different configuration formats. They should all update the gas limit value generated in their default configurations to 60M.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;In the past there has been some difficulty coordinating EL clients to update gas limit values in their default configurations. Therefore we suggest tying a new value to a hard fork release.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;A higher gas limit should not break any existing contracts. It is possible that with a higher limit new transactions could exceed the proposed 30M transaction gas limit, so the scheduling of these two EIPs should be coordinated.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Devnets will be stood up with nodes running all combinations of EL and CL clients in order to test if a gas limit of 60M is safe. Synthetic transactions will be created until blocks are full, and network and node health monitored. If bugs are discovered, client teams will patch them and then start the process again. If everything looks good, the gas limit will be increased incrementally.&lt;&#x2F;p&gt;
&lt;p&gt;Adversarial block constructions that would increase the worst-case size have already been researched and should not be a factor below 150M gas because this is close to where the current worst-case block size of 1.79 MiB would reach the current 10MiB CL gossip limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>RLP Execution Block Size Limit</title>
        <published>2025-04-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Giulio Rebuffo</name><uri>https://github.com/Giulio2002</uri>
	</author>
	
	<author>
		<name>Ben Adams</name><uri>https://github.com/benaadams</uri>
	</author>
	
	<author>
		<name>Storm Slivkoff</name><uri>https://github.com/sslivkoff</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7934/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7934-add-bytesize-limit-to-blocks/23589" />
        

        <id>https://wg-eips.ritovision.com/7934/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:7934"
            label="EIP-7934" />
        

        
        

        
        <summary type="html">Introduce a protocol-level cap on the maximum RLP-encoded block size to 10 MiB, including a 2 MiB margin for beacon block size.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7934/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces a protocol-level cap on the maximum RLP-encoded execution block size to 10 megabytes (MiB), which includes a margin of 2 MiB to account for beacon block sizes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, Ethereum does not enforce a strict upper limit on the encoded size of blocks. This lack of constraint can result in:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Network Instability&lt;&#x2F;strong&gt;: Extremely large blocks slow down propagation and increase the risk of temporary forks and reorgs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;DoS Risks&lt;&#x2F;strong&gt;: Malicious actors could generate exceptionally large blocks to disrupt network performance.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Additionally, blocks exceeding 10 MiB are not propagated by the consensus layer&#x27;s (CL) gossip protocol, potentially causing network fragmentation or denial-of-service (DoS) conditions.&lt;&#x2F;p&gt;
&lt;p&gt;By imposing a protocol-level limit on the RLP-encoded block size, Ethereum can ensure enhanced resilience against targeted attacks on block validation times. Adding an additional margin of 2MiB explicitly accommodates beacon block sizes, ensuring compatibility across network components.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;block-size-cap&quot;&gt;Block Size Cap&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Introduce constants:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MAX_BLOCK_SIZE&lt;&#x2F;code&gt; set to &lt;strong&gt;10 MiB (10,485,760 bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SAFETY_MARGIN&lt;&#x2F;code&gt; set to &lt;strong&gt;2MiB (2,097,152  bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;MAX_RLP_BLOCK_SIZE&lt;&#x2F;code&gt; calculated as &lt;code&gt;MAX_BLOCK_SIZE - MARGIN&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Any RLP-encoded block exceeding &lt;code&gt;MAX_RLP_BLOCK_SIZE&lt;&#x2F;code&gt; must be considered invalid.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thus add the following check to the Ethereum protocol:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;MAX_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10_485_760&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 10 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;SAFETY_MARGIN&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2_097_152&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;MAX_RLP_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SAFETY_MARGIN&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if true, the block is invalid and should be rejected&#x2F;not get built&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; exceed_max_rlp_block_size&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rlp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_RLP_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;changes-to-protocol-behavior&quot;&gt;Changes to Protocol Behavior&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Block Creation&lt;&#x2F;strong&gt;: Validators must ensure the total RLP-encoded size of any produced block does not exceed &lt;code&gt;MAX_RLP_BLOCK_SIZE&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Block Validation&lt;&#x2F;strong&gt;: Nodes must reject blocks whose RLP-encoded size exceeds &lt;code&gt;MAX_RLP_BLOCK_SIZE&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;protocol-adjustment&quot;&gt;Protocol Adjustment&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;All Ethereum client implementations must integrate this size check as part of block validation and propagation.&lt;&#x2F;li&gt;
&lt;li&gt;This limit applies independently of gas-related metrics.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-10-mib&quot;&gt;Why 10 MiB?&lt;&#x2F;h3&gt;
&lt;p&gt;A cap of 10 MiB aligns with the gossip protocol constraint in Ethereum&#x27;s consensus layer (CL). An additional 2MiB margin explicitly accounts for beacon block sizes, ensuring compatibility and consistent block propagation across the network. Blocks significantly larger than 10 MiB will not be broadcast by the CL, potentially leading to network fragmentation or denial-of-service scenarios.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This change is &lt;strong&gt;not backward-compatible&lt;&#x2F;strong&gt; with any blocks larger than the newly specified size limit. Validators and miners will need to ensure their block construction logic strictly respects this limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Restricting maximum block size provides inherent protection against deliberate oversized-block attacks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blob base fee bounded by execution cost</title>
        <published>2025-03-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Anders Elowsson</name><uri>https://github.com/anderselowsson</uri>
	</author>
	
	<author>
		<name>Ben Adams</name><uri>https://github.com/benaadams</uri>
	</author>
	
	<author>
		<name>Francesco D&#x27;Amato</name><uri>https://github.com/fradamt</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7918/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-blob-base-fee-bounded-by-price-of-blob-carrying-transaction/23271" />
        

        <id>https://wg-eips.ritovision.com/7918/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:7918"
            label="EIP-7918" />
        

        
        

        
        <summary type="html">Imposes that the price of GAS_PER_BLOB blob gas is greater than the price of BLOB_BASE_COST execution gas.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7918/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP assigns a reserve price &lt;code&gt;BLOB_BASE_COST * base_fee_per_gas&lt;&#x2F;code&gt; to blobs by introducing an &lt;code&gt;if&lt;&#x2F;code&gt;-clause in &lt;code&gt;calc_excess_blob_gas()&lt;&#x2F;code&gt;. Specifically, when the reserve price is higher than &lt;code&gt;GAS_PER_BLOB * base_fee_per_blob_gas&lt;&#x2F;code&gt;, the function will not subtract &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt; from &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt;, causing &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; to increase according to &lt;code&gt;blob_gas_used&lt;&#x2F;code&gt;, while keeping the per-block maximum increase unchanged. The proposal ensures that the blob fee market can function properly and that blob consumers pay at least a relevant fraction of the market rate for the compute they request from nodes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum uses a dynamic pricing auction to set the blob base fee, lowering the fee if less gas is consumed than &lt;code&gt;target_blob_gas = GAS_PER_BLOB * blobSchedule.target&lt;&#x2F;code&gt; and raising the fee if more gas is consumed. Such an auction can function well when the blob base fee represents the price signal, allowing the mechanism to control the real price for blob consumers. However, when execution costs dominate, the price signal is lost. The blob base fee then no longer represents a significant component of the total cost facing the consumer, and the protocol can no longer rely on the blob base fee to control the equilibrium quantity of blobs consumed.&lt;&#x2F;p&gt;
&lt;p&gt;The current mechanism can therefore end up repeatedly lowering the blob base fee until it eventually settles at 1 wei. A change in the blob base fee of 10% may under such circumstances shift the total cost of utilizing blobspace by just 0.0000001%. Whenever demand picks up, over an hour of near-full blocks is required to restore a market-clearing equilibrium fee, with the mechanism intermittently resorting to a first-price auction, considered a worse UX by blob consumers. The resulting spikiness in resource consumption is suboptimal for scaling blobspace. To alleviate this, the proposal imposes a reserve price that reflects execution costs, through a simple &lt;code&gt;if&lt;&#x2F;code&gt;-clause in &lt;code&gt;calc_excess_blob_gas()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The reserve price also fulfills a second function. Nodes must cryptographically verify KZG &lt;code&gt;proofs&lt;&#x2F;code&gt; to ensure that associated &lt;code&gt;commitments&lt;&#x2F;code&gt; correspond to provided blobs. This process is computationally expensive. It seems desirable to ensure that blob consumers pay at least some fraction of the market rate for the compute they impose on nodes. In this context, the execution base fee reflects how in-demand nodes&#x27; compute services are at the time that blob consumers request them.&lt;&#x2F;p&gt;
&lt;p&gt;By applying the reserve price to the blob base fee, the proposal jointly ensures that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The blob base fee update mechanism can function properly, by establishing a reserve price which is significant relative to L1 execution costs of blob consumers.&lt;&#x2F;li&gt;
&lt;li&gt;Blob consumers pay at least a relevant fraction of the market rate for the compute they request from nodes, with any additional fees for data determined independently in the blob fee market.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**13&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;functions&quot;&gt;Functions&lt;&#x2F;h3&gt;
&lt;p&gt;An &lt;code&gt;if&lt;&#x2F;code&gt;-clause is added to &lt;code&gt;calc_excess_blob_gas()&lt;&#x2F;code&gt; from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;. The function no longer subtracts &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt; when updating &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; if the price of a &lt;code&gt;blob&lt;&#x2F;code&gt; is below the price of &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; execution gas. The &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; for referencing target and max blobs was introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7840&#x2F;&quot;&gt;EIP-7840&lt;&#x2F;a&gt;. The current block&#x27;s &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; is used during processing. Thus, in the first block after a fork—when calculating &lt;code&gt;base_fee_per_blob_gas&lt;&#x2F;code&gt; via &lt;code&gt;get_base_fee_per_blob_gas(parent)&lt;&#x2F;code&gt;—&lt;code&gt;fake_exponential()&lt;&#x2F;code&gt; must use the &lt;em&gt;new&lt;&#x2F;em&gt; &lt;code&gt;blobSchedule.baseFeeUpdateFraction&lt;&#x2F;code&gt;. Likewise, the &lt;em&gt;new&lt;&#x2F;em&gt; &lt;code&gt;blobSchedule.max&lt;&#x2F;code&gt; and &lt;code&gt;blobSchedule.target&lt;&#x2F;code&gt; must be used in &lt;code&gt;calc_excess_blob_gas()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calc_excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    target_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; blobSchedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; target_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BLOB_BASE_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; get_base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; blobSchedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; blobSchedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; target_blob_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;fee-inelasticity-and-reserve-price&quot;&gt;Fee-inelasticity and reserve price&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal alleviates idiosyncrasies in the blob base fee auction. When a rollup&#x27;s costs are dominated by execution costs for the blob-carrying transactions, ZK proof verification, or priority fees, the protocol can no longer rely on the blob base fee to control the equilibrium quantity of blobs consumed. The fee update mechanism is unaware of the full price of the goods that it regulates the price for and therefore fails to converge on equilibrium in a timely manner.&lt;&#x2F;p&gt;
&lt;p&gt;We can express a simple real demand function for blobspace as&lt;&#x2F;p&gt;
&lt;p&gt;$Q(b + c).$&lt;&#x2F;p&gt;
&lt;p&gt;It maps the quantity of blobs demanded $Q$ to the blob base fee $b$ and the user&#x27;s execution costs, expressed &quot;per blob gas&quot;, $c$:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; execution_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;According to the &lt;em&gt;law of demand&lt;&#x2F;em&gt;, the lower the price $b+c$, the higher the demand. From the perspective of the blob base fee update mechanism, $c$ is fixed. If $c&amp;gt;0$, the demand curve will therefore have an &quot;inelasticity horizon&quot;, beyond which further reductions in $b$ no longer increase $Q$:&lt;&#x2F;p&gt;
&lt;p&gt;$\lim_{b \to 0} Q(b + c) = Q(c).$&lt;&#x2F;p&gt;
&lt;p&gt;In essence, the demand curve becomes a vertical line, where changes to the blob base fee $b$ no longer affect demand. Figure 1 illustrates this, with real demand curves (black to red) computed under four different execution base fees when purchasing two blobs. The hypothetical organic demand is illustrated in black. Any demand curve where execution costs are positive ($c&amp;gt;0$) eventually becomes vertical as the blob base fee falls. The protocol also uses a long-run perfectly inelastic supply curve (vertical blue line). Therefore, relatively small shifts in organic demand or the execution base fee (arrows) can lead to dramatic shifts in the equilibrium blob base fee. Importantly, the blob base fee will simply fall to the boundary of 1 wei whenever the execution cost is too high for consumers to achieve equilibrium formation at &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;.&#x2F;assets&#x2F;1.png&quot; alt=&quot;Figure 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.&lt;&#x2F;strong&gt; Hypothetical real demand for blobspace under different execution base fees (black to red lines). When execution cost dominates, the real demand curve becomes inelastic and parallel to the supply curve, leading the equilibrium fee to change dramatically even with small shifts in the demand curve (arrows). The proposal imposes that the equilibrium (square) forms on the edges of the upper-left quadrant, at the intersection between the target supply curve and demand or along the dashed line representing possible reserve price equilibria accounting for execution costs.&lt;&#x2F;p&gt;
&lt;p&gt;To improve the fee update mechanism, a reserve price is specified below which $b$ cannot be reduced. Specifically, we define a constant &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; and in &lt;code&gt;calc_excess_blob_gas&lt;&#x2F;code&gt; do not subtract &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;BLOB_BASE_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This means that the reserve blob base fee becomes &lt;code&gt;BLOB_BASE_COST * base_fee_per_gas &#x2F; GAS_PER_BLOB&lt;&#x2F;code&gt; and that the ratio between the reserve price for the blob base fee and the execution base fee is fixed to: &lt;code&gt;BLOB_BASE_COST &#x2F; GAS_PER_BLOB&lt;&#x2F;code&gt;. This ratio is &lt;code&gt;1&#x2F;16&lt;&#x2F;code&gt; with the proposed constant.&lt;&#x2F;p&gt;
&lt;p&gt;The blob fee&#x27;s share of the total price will with the reserve price always be at least &lt;code&gt;BLOB_BASE_COST &#x2F; (BLOB_BASE_COST + execution_cost)&lt;&#x2F;code&gt;. This is why the equilibrium under the reserve price (dashed line in Figure 1) is situated a constant fraction below the black organic demand curve formed under a zero execution base fee. The equilibrium (squares) must then form somewhere along the edge of the upper-left quadrant, bounded by the blue supply curve and the dashed curve representing possible reserve price equilibria under real demand.&lt;&#x2F;p&gt;
&lt;p&gt;The demand curve could potentially be somewhat inelastic even under zero execution costs. This would however just be another reason to move forward with this proposal. Regardless of the exact shape of the demand curve—which of course will remain unknown and can vary going forward—the proposal is based on something tangible affecting blob consumers. This makes it a justified neutral bound on the blob base fee.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blob-kzg-proof-verification-cost&quot;&gt;Blob KZG proof verification cost&lt;&#x2F;h3&gt;
&lt;p&gt;EIP-4844 introduced the first phase of Ethereum&#x27;s data availability sampling (DAS) roadmap. Validators on the consensus layer (CL) verify that the KZG &lt;code&gt;commitments&lt;&#x2F;code&gt; in the payload correspond to the provided &lt;code&gt;blobs&lt;&#x2F;code&gt; by cryptographically verifying the accompanying KZG &lt;code&gt;proofs&lt;&#x2F;code&gt;. Execution layer (EL) nodes must also validate the &lt;code&gt;tx_payload_body&lt;&#x2F;code&gt; and verify the wrapped data (blobs, commitments, and proofs) for every blob entering a node&#x27;s tx pool. The computational requirements for verifying a KZG proof for an entire blob are slightly higher than those for verifying a KZG proof for a single point on that blob; the latter is the specific operation covered by the &lt;code&gt;POINT_EVALUATION_PRECOMPILE_GAS&lt;&#x2F;code&gt; (50000) charged to smart contracts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7594&#x2F;&quot;&gt;EIP-7594&lt;&#x2F;a&gt; introduces PeerDAS. It changes the compute requirements due to the reliance on blob cells and their individual proofs. The exact specification is not yet fully settled, but this is a rough guideline:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;EL nodes batch-verify &lt;code&gt;CELLS_PER_EXT_BLOB&lt;&#x2F;code&gt; (128) cell proofs for each blob before including a tx carrying that blob in their tx pool. This verification (e.g., using &lt;code&gt;verify_cell_kzg_proof_batch&lt;&#x2F;code&gt;) is roughly 15 times more expensive than the compute associated with a single &lt;code&gt;POINT_EVALUATION_PRECOMPILE_GAS&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Full nodes verify 4 custodied columns, each column containing one cell from all blobs referenced in the payload. Each column&#x27;s cell proofs can be batch-verified (also applicable below).&lt;&#x2F;li&gt;
&lt;li&gt;Supernodes verify 128 custodied columns, each column containing one cell from all blobs referenced in the payload.&lt;&#x2F;li&gt;
&lt;li&gt;Validators between full nodes and supernodes will custody between 4-128 columns.&lt;&#x2F;li&gt;
&lt;li&gt;Nodes peer-sample &lt;code&gt;SAMPLES_PER_SLOT&lt;&#x2F;code&gt; (8) columns each slot (in addition to custodied columns).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The ability on the CL to jointly process cell proofs of a column (from all blobs) through batching reduces the compute time spent per blob as the number of blobs increases. It is further possible to batch all columns jointly or to parallelize the processing across columns. When accounting for the prospect of parallelization for the CL, it is however worth remembering that the point evaluation proof verification performed by rollups using the precompile also lends itself to parallelization. This means that a comparison between the point evaluation and the sequential processing of blobs (batched per column) is still relevant (because &lt;em&gt;both&lt;&#x2F;em&gt; could be parallelized).&lt;&#x2F;p&gt;
&lt;p&gt;Figure 2 shows verification time per blob divided by the measured execution time of a single point evaluation operation (performed by the &lt;code&gt;VerifyKZGProof&lt;&#x2F;code&gt; precompile) for various configurations. The figure indicates that blobs under the current Fusaka PeerDAS specification will subject nodes to rather heavy compute requirements—when compared to the single point evaluation proof verification that a smart contract is charged &lt;code&gt;POINT_EVALUATION_PRECOMPILE_GAS&lt;&#x2F;code&gt; for. A full node would for example do the EL mempool verification for all blobs propagated p2p (15x), sample 8 columns (2x at 32 blobs when batching columns sequentially), and custody 4 designated columns (1x). How to price the KZG proof verification is however a complex question given the varying contexts in which it is performed. The proposed constant &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; is indicated by a green line in Figure 2. It is relatively moderate in comparison with the compute costs imposed on nodes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;.&#x2F;assets&#x2F;2.png&quot; alt=&quot;Figure 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 2.&lt;&#x2F;strong&gt; Verification time per blob relative to one point evaluation on an Apple M2 Max with 12 cores. The EL mempool verification (red) takes 15 times longer in the worst case, regardless of the blob target. The per-blob verification time of columns depends on the number of custodied&#x2F;sampled columns and falls with an increase in the blob target due to speed-ups from processing all cells of a column jointly. The constant &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; is relatively moderate in comparison with the compute costs that blobs impose on nodes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;designing-for-the-future&quot;&gt;Designing for the future&lt;&#x2F;h3&gt;
&lt;p&gt;The price of storing a fixed amount of data has fallen over the last 80 years. Technological progress generally brings down the unit cost of data services, following Nielsen’s law and Moore’s law. The ETH-denominated price per blob should likewise fall as Ethereum increases blob throughput. This effect is reinforced because a higher aggregate ETH-denominated blob revenue (which is distributed to ETH token holders via the burn) increases the fiat-denominated value of the ETH token, ceteris paribus. There is thus an upper bound on the blob base fee—a bound that falls as Ethereum scales. The same reflexivity applies to the execution base fee.&lt;&#x2F;p&gt;
&lt;p&gt;In this light, the proposal can be understood as a design for the future. Fixed thresholds not relating to blob quantity or the execution fee may not be sustainable. In a scenario where Ethereum sells more blobs per block, the equilibrium blob base fee should ideally have a relatively lower floor. Any fixed threshold (not relating to the execution base fee or blob quantity) would need to be gradually readjusted to retain the same relative impact.&lt;&#x2F;p&gt;
&lt;p&gt;If Ethereum increases blob throughput by several orders of magnitude but does &lt;em&gt;not&lt;&#x2F;em&gt; scale blockspace, such that the execution base fee remains high, the reserve price of &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; execution gas would however still become too high. At 1000 blobs and 30M execution gas per block, Ethereum would derive just over 1&#x2F;5th (21.5%) of its income from blob gas even when blobs are strictly sold at the reserve price. This implies a too high &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt;, but 1000 blobs and 30M execution gas is not the trajectory that Ethereum currently is on. If Ethereum scales blockspace and blobspace roughly in synchrony, it is reasonable to expect that the reserve price remains at the desired level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delayed-response-during-a-quick-rise-in-execution-fees&quot;&gt;Delayed response during a quick rise in execution fees&lt;&#x2F;h3&gt;
&lt;p&gt;When the &lt;code&gt;if&lt;&#x2F;code&gt; statement concludes that Ethereum operates in the execution-fee-led pricing regime, the blob base fee rises in accordance with &lt;code&gt;blob_gas_used * (max - target) &#x2F;&#x2F; max&lt;&#x2F;code&gt;, without subtracting &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt;. This is an intuitive way to return to the blob-fee-led pricing regime, retaining the same maximum fee increase while not allowing for a decrease. If the execution base fee rises quickly, there may be a few blocks before the blob base fee catches up (during which &lt;code&gt;target_blob_gas&lt;&#x2F;code&gt; will never be subtracted). This is arguably not an issue, and the smooth response in the blob base fee under these circumstances may even be seen as a benefit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;empirical-analysis&quot;&gt;Empirical analysis&lt;&#x2F;h3&gt;
&lt;p&gt;Figures 3-4 show price evolution over three weeks in November 2024, when the average execution base fee was around 16 gwei, as well as in March 2025, when the average was around 1.3 gwei. The proposed reserve fee is applied directly to the original data, without accounting for its potential effect on the equilibrium fee. The equilibrium blob base fee would in reality rise from the threshold level once demand at this fee is above target supply. EIP-7918 imposes the maximum of the two curves, indicated in darker colors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;.&#x2F;assets&#x2F;3.png&quot; alt=&quot;Figure 3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 3.&lt;&#x2F;strong&gt; Blob base fee evolution with the current fee market (black) and the proposed reserve fee (blue), during three weeks of November 2024 when the average execution base fee was around 16 gwei. EIP-7918 imposes the maximum of the two curves, as indicated in darker colors. Thresholding is applied directly to the original data, without accounting for its effect on the equilibrium fee.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;.&#x2F;assets&#x2F;4.png&quot; alt=&quot;Figure 4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 4.&lt;&#x2F;strong&gt; Blob base fee evolution with the current fee market (black) and the proposed reserve fee (blue), during three weeks of March 2025 when the average execution base fee was around 1.3 gwei. EIP-7918 imposes the maximum of the two curves, as indicated in darker colors. Thresholding is applied directly to the original data, without accounting for its effect on the equilibrium fee.&lt;&#x2F;p&gt;
&lt;p&gt;Figure 5 shows histograms for observed fees and the maximum of the two curves for the four-month period from November 2024 (start of Figure 3&#x27;s data period) through March 2025 (end of Figure 4&#x27;s data period), corresponding to approximately 900k blocks beginning at block number 22075724. The histograms employ 100 log-spaced bins per decade (factor-of-ten increase), which are smoothed using a Hanning window of width 21 with mirror-reflected edges.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;.&#x2F;assets&#x2F;5.png&quot; alt=&quot;Figure 5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 5.&lt;&#x2F;strong&gt; Histogram of the blob base fee when there is no threshold or when applying EIP-7918 (dashed combination of the darker black and blue curves from previous figures), with light smoothing applied. A four-month period from November 2024 through March 2025 was analyzed. Thresholding is applied directly to the original data, without accounting for its effect on the equilibrium fee.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The blob base fee will settle at a level where a blob costs at least &lt;code&gt;BLOB_BASE_COST&lt;&#x2F;code&gt; execution gas. To the best of the authors&#x27; knowledge, there are no security risks associated with this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Deterministic proposer lookahead</title>
        <published>2025-03-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Lin Oshitani</name><uri>https://github.com/linoscope</uri><email>lin@nethermind.io</email>
	</author>
	
	<author>
		<name>Justin Drake</name><uri>https://github.com/JustinDrake</uri><email>justin@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7917/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7917-deterministic-proposer-lookahead/23259" />
        

        <id>https://wg-eips.ritovision.com/7917/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7917"
            label="EIP-7917" />
        

        
        

        
        <summary type="html">Pre-calculate and store a deterministic proposer lookahead in the beacon state at the start of every epoch</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7917/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;At the start of each epoch, pre-calculate and store in the &lt;code&gt;beacon_state&lt;&#x2F;code&gt; a deterministic &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; for the next &lt;code&gt;MIN_SEED_LOOKAHEAD + 1&lt;&#x2F;code&gt; epochs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Unlike RANDAO seeds, which have a deterministic lookahead of at least &lt;code&gt;MIN_SEED_LOOKAHEAD == 1&lt;&#x2F;code&gt; epochs, the beacon proposer schedule of epoch &lt;code&gt;N + 1&lt;&#x2F;code&gt; is not fully predictable from the beacon state during epoch &lt;code&gt;N&lt;&#x2F;code&gt;. The reason is that, under certain edge cases, the effective balances (EBs) of active validators—themselves used as input for proposer election in epoch &lt;code&gt;N + 1&lt;&#x2F;code&gt;—can change within epoch &lt;code&gt;N&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Based preconfirmation protocols rely on a deterministic proposer schedule for smooth operations. Since the beacon genesis, slashings and penalties that accumulate to at least 1 ETH can change EBs of active validators and lead to an unpredictable proposer schedule despite the RANDAO seed being known ahead of time. The increase of MaxEB with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7251&#x2F;&quot;&gt;EIP-7251&lt;&#x2F;a&gt; increases effective balance unpredictability because rewards that accumulate to at least 1 ETH, validator consolidations, and deposits can grow EBs of active validators beyond 32 ETH.&lt;&#x2F;p&gt;
&lt;p&gt;Besides fixing next-epoch proposer schedule non-determinism, this EIP makes it possible for the proposer schedule of the next epoch to be accessible to the application layer via the beacon root and a simple Merkle proof. This highly simplifies the implementation of on-chain components for based preconfirmation protocols.&lt;&#x2F;p&gt;
&lt;p&gt;Introducing a fully deterministic lookahead fixes a long-standing beacon chain design oversight, as highlighted by Danny Ryan&#x27;s comment below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7917&#x2F;.&#x2F;assets&#x2F;lookahead-comment.png&quot; alt=&quot;Danny Ryan&amp;#39;s comment on proposer lookahead&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With this change, it will no longer be possible for validators to grind effective balances to manipulate the proposer schedule of the next epoch, and the analysis of effective balance grinding will collapse from what is currently a subtle analysis of EB edge cases to a trivial security analysis. Finally, the proposer lookahead gives CL clients ahead-of-time visibility over the next proposer which may simplify implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;BeaconState&lt;&#x2F;code&gt; container is extended with a &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; field, which is a vector of validator indices covering the full visible lookahead period, starting from the beginning of the current epoch to the next &lt;code&gt;MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt; epochs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Vector&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;ValidatorIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;MIN_SEED_LOOKAHEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SLOTS_PER_EPOCH&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 example, &lt;code&gt;proposer_lookahead[0]&lt;&#x2F;code&gt; is the validator index for the first proposer in the current epoch, &lt;code&gt;proposer_lookahead[SLOTS_PER_EPOCH + 4]&lt;&#x2F;code&gt; is the validator index for the fifth proposer in the next epoch, and so forth.&lt;&#x2F;p&gt;
&lt;p&gt;The function &lt;code&gt;get_beacon_proposer_index&lt;&#x2F;code&gt; is modified to use the pre-calculated &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; instead of calculating proposer indices on-demand.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_beacon_proposer_index&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ValidatorIndex&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Return the beacon proposer index at the current slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SLOTS_PER_EPOCH&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;At the epoch boundary, the &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; is updated by shifting out the current epoch’s lookahead and appending the new one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; process_epoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    process_proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; process_proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last_epoch_start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SLOTS_PER_EPOCH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Shift out proposers in the first epoch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;last_epoch_start&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;SLOTS_PER_EPOCH&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fill in the last epoch with new proposer indices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last_epoch_proposers&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_beacon_proposer_indices&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Epoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;get_current_epoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MIN_SEED_LOOKAHEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proposer_lookahead&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;last_epoch_start&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; last_epoch_proposers&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_beacon_proposer_indices&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;    state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Epoch&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&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Vector&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;ValidatorIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SLOTS_PER_EPOCH&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Return the proposer indices for the given ``epoch``.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    indices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_active_validator_indices&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_seed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DOMAIN_BEACON_PROPOSER&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; compute_proposer_indices&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; seed&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; indices&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compute_proposer_indices&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;    state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BeaconState&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; seed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; indices&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;ValidatorIndex&lt;&#x2F;span&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;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Vector&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;ValidatorIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SLOTS_PER_EPOCH&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Return the proposer indices for the given ``epoch``.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; compute_start_slot_at_epoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    seeds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; uint_to_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Slot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;start_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;SLOTS_PER_EPOCH&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;compute_proposer_index&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; indices&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; seed&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; seeds&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;Furthermore, the first block after the fork will calculate all lookaheads for epochs up to &lt;code&gt;MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt; ahead and fill the &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; field in the beacon state.&lt;&#x2F;p&gt;
&lt;p&gt;See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;cbaa0063979168a94a9c7821f366c6a221319c8e&#x2F;specs&#x2F;fulu&#x2F;beacon-chain.md&quot;&gt;updated beacon chain specs&lt;&#x2F;a&gt; in consensus-specs for more details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;considered-alternatives&quot;&gt;Considered Alternatives&lt;&#x2F;h3&gt;
&lt;p&gt;An alternative approach would be to cache the effective balances at the start of epoch &lt;code&gt;N&lt;&#x2F;code&gt; so it can be used to calculate the proposer lookahead at the start of epoch &lt;code&gt;N+MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt;. However, this approach would require additional footprint in the beacon state, and would not be able to provide the proposer lookahead to the EVM via the beacon root.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;single-secret-leader-election-compatibility&quot;&gt;Single Secret Leader Election Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;In the future, we may introduce a Single Secret Leader Election (SSLE) mechanism in which only the selected validator knows their role until they propose a block. However, current SSLE designs still rely on a lookahead, albeit an encrypted one. In such designs, we could reuse the &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; field by changing its type to something like &lt;code&gt;List[EncryptedValidatorIndex]&lt;&#x2F;code&gt;. And if a construction were to remove lookahead entirely, we could simply set &lt;code&gt;proposer_lookahead&lt;&#x2F;code&gt; to an empty list, meaning this wouldn’t be a blocker.&lt;&#x2F;p&gt;
&lt;p&gt;That said, any such changes would introduce additional complexity around preconfirmation protocols, but that complexity arises regardless of this EIP. Furthermore, APS (Attester Proposer Separation) envisions more sophisticated (i.e., more DDoS‑resistant) execution proposers, reducing the need for SSLE.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;added-computation-at-the-epoch-boundary&quot;&gt;Added Computation at the Epoch Boundary&lt;&#x2F;h3&gt;
&lt;p&gt;Before this EIP, consensus clients only needed to compute the current proposer’s index at each slot. With the changes introduced by this EIP, they must calculate the entire epoch’s proposer schedule at the start of each epoch. However, computing the proposer index is light, involving sampling validators until we reach a validator with sufficient effective balance to be selected as a proposer. Still, testing is needed to confirm that these additional calculations do not create performance bottlenecks in practice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;cbaa0063979168a94a9c7821f366c6a221319c8e&#x2F;tests&#x2F;core&#x2F;pyspec&#x2F;eth2spec&#x2F;test&#x2F;fulu&quot;&gt;the spec tests&lt;&#x2F;a&gt; in consensus-specs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;malicious-lookahead-alteration&quot;&gt;Malicious Lookahead Alteration&lt;&#x2F;h3&gt;
&lt;p&gt;A critical consideration for any proposer election mechanism is preventing validators from manipulating lookahead to gain an unfair advantage. This proposal does not increase the chances of such attacks, as we do not alter the “RANDAO delay” used in the lookahead—the lookahead of epoch &lt;code&gt;N&lt;&#x2F;code&gt; is still determined by the RANDAO of epoch &lt;code&gt;N - MIN_SEED_LOOKAHEAD - 1&lt;&#x2F;code&gt; (which becomes available at the start of epoch &lt;code&gt;N - MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt;). The only difference is that it changes the “effective balances delay”: rather than using the effective balances (EB) at the start of epoch &lt;code&gt;N&lt;&#x2F;code&gt;, it now uses the EB at the start of epoch &lt;code&gt;N - MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, by aligning the RANDAO and effective balances in this way, the proposal removes any chance of validators adjusting their EB after seeing the RANDAO outcome, which is an attack vector to consider. No such attack has been found so far, but this change removes the possibility, hence simplifying the security analysis.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Signature Verifiers</title>
        <published>2025-03-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	<author>
		<name>Ernesto García</name><uri>https://github.com/ernestognw</uri>
	</author>
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	<author>
		<name>Aryeh Greenberg</name><uri>https://github.com/arr00</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7913/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7913-key-verifiers/23262" />
        

        <id>https://wg-eips.ritovision.com/7913/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7913"
            label="ERC-7913" />
        

        
        

        
        <summary type="html">Interface for the verification of signatures by address-less keys</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7913/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Externally Owned Accounts (EOA) can sign messages with their associated private keys. Additionally &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; defines a method for signature verification by smart accounts such as multisig. In both cases the identity of the signer is an ethereum address. We propose a standard to extend this concept of signer description, and signature verification, to keys that do not have an ethereum identity of their own, in the sense that they don&#x27;t have their own address to represent them.&lt;&#x2F;p&gt;
&lt;p&gt;This new mechanism can be used to integrate new signers such as non-ethereum cryptographic curves, hardware devices, or even email addresses. This is particularly relevant when dealing with things like social-recovery of smart accounts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the development of account abstraction, there is an increasing need for non-ethereum signature verification. Cryptographic algorithms besides the natively supported secp256k1 are being used for controlling smart accounts. In particular, curves such as secp256r1 (supported by many mobile devices) and RSA keys (that are distributed by traditional institutions) are widely available. Beyond these two examples, we also see the emergence of ZK solutions for signing with emails or JWT from big Web2 services.&lt;&#x2F;p&gt;
&lt;p&gt;All these signature mechanisms have one thing in common: they do not have a canonical ethereum address to represent them onchain. While users could deploy ERC-1271 compatible contracts for each key individually, this would be cumbersome and expensive. As account abstraction tries to separate account addresses (that hold assets) from the key that controls them, giving fixed on-chain addresses to keys (and possibly sending assets to these addresses by mistake) is not the right approach. Instead, using a small number of verifier contracts that can process signatures in a standard way, and having the accounts rely on these verifiers, feels like the correct approach. This has the advantage that once the verifier is deployed, any key can be represented using a &lt;code&gt;(verifier, key)&lt;&#x2F;code&gt; pair without requiring any setup cost.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;(verifier, key)&lt;&#x2F;code&gt; pairs can be given permission to control a smart account, perform social recovery, or do any other operation without ever having a dedicated on-chain address. Systems that want to adopt this approach need to transition away from the model where signers are identified by their address to a new model where signers may not have an address, and are identified by a &lt;code&gt;bytes&lt;&#x2F;code&gt; object.&lt;&#x2F;p&gt;
&lt;p&gt;This definition is backward compatible with EOA and ERC-1271 contracts: in that case, we use the address of the identity (EOA or contract) as the verifier and the key is empty.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nomenclature&quot;&gt;Nomenclature&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Keys are represented using &lt;code&gt;bytes&lt;&#x2F;code&gt; objects of arbitrary length. For example a P256 or RSA public key. Keys MUST NOT be empty.&lt;&#x2F;li&gt;
&lt;li&gt;Verifiers are smart contracts in charge of signature verification for a given type of key. They have an ethereum address.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;signature-verifier-interface&quot;&gt;Signature Verifier interface&lt;&#x2F;h3&gt;
&lt;p&gt;Verifiers MUST implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7913SignatureVerifier&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies `signature` as a valid signature of `hash` by `key`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * MUST return the bytes4 magic value 0x024ad318 (IERC7913SignatureVerifier.verify.selector) if the signature is valid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * SHOULD return 0xffffffff or revert if the signature is not valid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * SHOULD return 0xffffffff or revert if the key is empty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Verifiers SHOULD be stateless.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Verifiers can be used to avoid deploying many ERC-1271 &quot;identity contract&quot; (one per key), which would be expensive. Using this model, new keys can be used without any deployment costs.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-1271 already covers the cases were a key is not necessary. To avoid ambiguity, the verifiers contracts should not support (or be expected to support) empty keys. Signers that are 20 bytes long (empty key) should be handled using ERC-1271.&lt;&#x2F;p&gt;
&lt;p&gt;Consistency with existing systems (ecrecover and ERC-1271) requires the message to be &lt;code&gt;bytes32&lt;&#x2F;code&gt; hash. These are usually produced following &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;ERC-712&lt;&#x2F;a&gt;. Cryptographic systems that use different hashing methods SHOULD see this hash as a message, and possibly rehash it following the relevant standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;A system can support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7913&#x2F;&quot;&gt;ERC-7913&lt;&#x2F;a&gt; signers alongside EOAs and ERC-1271 in the following way.&lt;&#x2F;p&gt;
&lt;p&gt;A signer is a &lt;code&gt;bytes&lt;&#x2F;code&gt; object that is the concatenation of an address and optionally a key: &lt;code&gt;verifier || key&lt;&#x2F;code&gt;. A signer is at least 20 bytes long.&lt;&#x2F;p&gt;
&lt;p&gt;Given a signer &lt;code&gt;signer&lt;&#x2F;code&gt;, a message hash &lt;code&gt;hash&lt;&#x2F;code&gt;, and a signature &lt;code&gt;sign&lt;&#x2F;code&gt;, verification is done as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if &lt;code&gt;signer.length &amp;lt; 20&lt;&#x2F;code&gt;: verification fails;&lt;&#x2F;li&gt;
&lt;li&gt;split &lt;code&gt;signer&lt;&#x2F;code&gt; into &lt;code&gt;(verifier, key)&lt;&#x2F;code&gt; with &lt;code&gt;verifier&lt;&#x2F;code&gt; being the first 20 bytes and &lt;code&gt;key&lt;&#x2F;code&gt; being the rest (potentially empty)&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;key&lt;&#x2F;code&gt; is empty, then consider that &lt;code&gt;verifier&lt;&#x2F;code&gt; is the identity.
&lt;ul&gt;
&lt;li&gt;verification is done using ERC-1271&#x27;s isValidSignature if there is code at &lt;code&gt;verifier&lt;&#x2F;code&gt; address, or ecrecover otherwise&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;key&lt;&#x2F;code&gt; is not empty, call &lt;code&gt;IERC7913SignatureVerifier(verifier).verify(key, hash, signature)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;if the return value is the expected magic value (&lt;code&gt;0x024ad318&lt;&#x2F;code&gt;) then verification is successful,&lt;&#x2F;li&gt;
&lt;li&gt;otherwise, verification fails.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;In solidity, signature verification could be implemented in the following library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;SignatureChecker&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;cryptography&#x2F;SignatureChecker.sol&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Extention of openzeppelin&amp;#39;s SignatureChecker library&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;library&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SignatureCheckerExtended&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSignatureNow&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; SignatureChecker&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSignatureNow&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&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&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7913SignatureVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;verify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; magic&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;          return&lt;&#x2F;span&gt;&lt;span&gt; magic &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; IERC7913SignatureVerifier&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;verify&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&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;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;          return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Signer may be used for anything from smart account session key (with a short lifetime of a few hours&#x2F;days) to social recovery &quot;guardians&quot; that may only be used several years after they are setup. In order to ensure that these signers remain valid &quot;in perpetuity&quot;, the verifier contract should be trustless. This means that the verifiers should not be upgradeable contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Verifiers should also not depend on any value that can be modified after deployment. In solidity terms, the &lt;code&gt;verify&lt;&#x2F;code&gt; function should be pure. Any parameters that are involved in signature verification should either be part of the key, or part of immutable code of the verifier. Using &lt;code&gt;immutable&lt;&#x2F;code&gt; variable (in solidity) would be safe. The stateless aspect of the verifier also ensure compliance (of the verifier) with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7562&#x2F;&quot;&gt;ERC-7562&lt;&#x2F;a&gt; scope rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>eth_config JSON-RPC Method</title>
        <published>2025-03-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Danno Ferrin</name><uri>https://github.com/shemnon</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7910/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eth-config-json-rpc-method/23183" />
        

        <id>https://wg-eips.ritovision.com/7910/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7910"
            label="EIP-7910" />
        

        
        

        
        <summary type="html">A JSON-RPC method that describes the configuration of the current and next fork</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7910/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This document describes an RPC method that provides node-relevant configuration data for the current, next, and last known forks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Throughout Ethereum&#x27;s history, there have been multiple instances where a client was not correctly configured for an upcoming hard fork, causing it to fall out of consensus when the fork boundary was crossed. Most incidents have been minor, such as a single client forking the chain in proof-of-work or having its blocks orphaned in proof-of-stake.&lt;&#x2F;p&gt;
&lt;p&gt;The most significant occurrence was during the Pectra activation on the Holešky testnet. Four out of six clients on the network had an incorrect configuration for the deposits contract. Instead of being orphaned, the incorrect chain was justified, and the side effects persist on Holešky even after reaching finality.&lt;&#x2F;p&gt;
&lt;p&gt;By providing an RPC method that allows clients to report key configuration variables before the next hard fork, operations teams can gain greater confidence that clients are correctly configured and prepared for upcoming forks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;target-audience-and-use-cases&quot;&gt;Target Audience and Use Cases&lt;&#x2F;h3&gt;
&lt;p&gt;This method is intended for node operators, validator teams, and network monitoring tools to verify client readiness for upcoming forks. Use cases include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Automated pre-fork validation scripts comparing &lt;code&gt;eth_config&lt;&#x2F;code&gt; outputs across nodes.&lt;&#x2F;li&gt;
&lt;li&gt;Manual checks by validator operators to ensure alignment with fork specifications.&lt;&#x2F;li&gt;
&lt;li&gt;Debugging by client developers to identify configuration mismatches.&lt;&#x2F;li&gt;
&lt;li&gt;Automated checks by Consensus Layer counterparties.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Clients MUST expose a new RPC method to report the current functional configuration and the expected next configuration via the standard JSON-RPC port.&lt;&#x2F;p&gt;
&lt;p&gt;Clients MAY also expose this method through the Engine API.&lt;&#x2F;p&gt;
&lt;p&gt;Clients MAY use these configuration objects to manage their per-fork configurations, though they SHOULD NOT simply return unprocessed configuration data.&lt;&#x2F;p&gt;
&lt;p&gt;When reporting the current, next and last configurations, clients MUST include every configuration parameter specified in this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;Clients MUST return up-to-date configuration values, reflecting the most recent block header they provide. If clients cache the configuration, they MUST ensure such caches are purged when fork boundaries are crossed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;configuration-rpc&quot;&gt;Configuration RPC&lt;&#x2F;h3&gt;
&lt;p&gt;A new JSON-RPC API, &lt;code&gt;eth_config&lt;&#x2F;code&gt;, is introduced. It takes no parameters and returns the result object specified in the next section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;result-object-structure&quot;&gt;Result Object Structure&lt;&#x2F;h3&gt;
&lt;p&gt;The RPC response contains three members: &quot;current&quot;, &quot;next&quot;, and &quot;last&quot;. These members contain the configuration object currently in effect, the next configuration, and the last known configuration, respectively. &quot;next&quot; and &quot;last&quot; will be &lt;code&gt;null&lt;&#x2F;code&gt; if the client is not configured to support a future fork. &quot;next&quot; and &quot;last&quot; members will contain the same configuration in the case where the next configured fork is also the last configured fork.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;members-of-the-configuration-object&quot;&gt;Members of the Configuration Object&lt;&#x2F;h3&gt;
&lt;p&gt;Each configuration object MUST contain the following members, presented in alphabetical order. This RPC assumes the network is post-merge, and no accommodations are specified for proof-of-work-related issues.&lt;&#x2F;p&gt;
&lt;p&gt;Future forks may add, adjust, remove, or update members. The respective changes MUST be defined in either their EIPs or their respective meta-EIPs. Added members MUST be alphabetically sorted, so simply naming the new members is sufficient definition.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;activationtime&quot;&gt;&lt;code&gt;activationTime&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The fork activation timestamp, represented as a JSON number in Unix epoch seconds (UTC). For the &quot;current&quot; configuration, this reflects the actual activation time; for &quot;next&quot; and &quot;last&quot;, it is the scheduled time.&lt;&#x2F;p&gt;
&lt;p&gt;Activation time is required. If a fork is activated at genesis, the value &lt;code&gt;0&lt;&#x2F;code&gt; is used. If the fork is not scheduled to be activated or its activation time is unknown, it should not be in the RPC results.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;blobschedule&quot;&gt;&lt;code&gt;blobSchedule&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The blob configuration parameters for the specific fork, as defined in the genesis file. This is a JSON object with three members—&lt;code&gt;baseFeeUpdateFraction&lt;&#x2F;code&gt;, &lt;code&gt;max&lt;&#x2F;code&gt;, and &lt;code&gt;target&lt;&#x2F;code&gt;—all represented as JSON numbers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;chainid&quot;&gt;&lt;code&gt;chainId&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The chain ID of the current network, presented as a string with an unsigned &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed hexadecimal number, with all leading zeros removed, in lower case. This specification does not support chains without a chain ID or with a chain ID of zero.&lt;&#x2F;p&gt;
&lt;p&gt;For purposes of canonicalization, this value must always be a string.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;forkid&quot;&gt;&lt;code&gt;forkId&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; value as specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6122&#x2F;&quot;&gt;EIP-6122&lt;&#x2F;a&gt; of the specific fork, presented as an unsigned &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed hexadecimal number, with zeros left-padded to a four-byte length, in lower case.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;precompiles&quot;&gt;&lt;code&gt;precompiles&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;A representation of the active precompile contracts for the fork. If a precompiled contract is replaced by an on-chain contract—or removed—then it is not included.&lt;&#x2F;p&gt;
&lt;p&gt;This is a JSON object where the members are the agreed-upon names for each contract, typically specified in the EIP defining that contract, and the values are the 20-byte &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed hexadecimal addresses of the precompiles (with zeros preserved), in lower case.&lt;&#x2F;p&gt;
&lt;p&gt;For Cancun, the contract names are (in order): &lt;code&gt;ECREC&lt;&#x2F;code&gt;, &lt;code&gt;SHA256&lt;&#x2F;code&gt;, &lt;code&gt;RIPEMD160&lt;&#x2F;code&gt;, &lt;code&gt;ID&lt;&#x2F;code&gt;, &lt;code&gt;MODEXP&lt;&#x2F;code&gt;, &lt;code&gt;BN254_ADD&lt;&#x2F;code&gt;, &lt;code&gt;BN254_MUL&lt;&#x2F;code&gt;, &lt;code&gt;BN254_PAIRING&lt;&#x2F;code&gt;, &lt;code&gt;BLAKE2F&lt;&#x2F;code&gt;, &lt;code&gt;KZG_POINT_EVALUATION&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For Prague, the added contracts are (in order): &lt;code&gt;BLS12_G1ADD&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_G1MSM&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_G2ADD&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_G2MSM&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_PAIRING_CHECK&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_MAP_FP_TO_G1&lt;&#x2F;code&gt;, &lt;code&gt;BLS12_MAP_FP2_TO_G2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For Osaka, the added contract is: &lt;code&gt;P256VERIFY&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;systemcontracts&quot;&gt;&lt;code&gt;systemContracts&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;A JSON object representing system-level contracts relevant to the fork, as introduced in their defining EIPs. Keys are the contract names (e.g., &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt;) from the first EIP where they appeared, sorted alphabetically. Values are 20-byte addresses in &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed hexadecimal form, with leading zeros preserved, in lower case. Omitted for forks before Cancun.&lt;&#x2F;p&gt;
&lt;p&gt;For Cancun, the only system contract is &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For Prague, the system contracts are (in order) &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt;, &lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;, &lt;code&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;code&gt;, &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt;, and &lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Future forks MUST define the list of system contracts in their meta-EIPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blob-parameter-only-bpo-forks&quot;&gt;Blob Parameter Only (BPO) Forks&lt;&#x2F;h3&gt;
&lt;p&gt;BPO forks should be interpreted as new forks, taking the parent fork as base (recursively, if the parent fork is also a BPO) and updating only the appropriate values in the &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; object to produce the new fork configuration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-enumerate-precompiles-and-in-general-why-track-a-particular-config-item&quot;&gt;Why Enumerate Precompiles? (And in General, Why Track a Particular Config Item?)&lt;&#x2F;h3&gt;
&lt;p&gt;The purpose of this specification is to enable nodes to advertise, prior to a fork, that they have the correct configurations loaded and ready. Past testnet and Ethereum Mainnet forks have revealed clients with incorrect precompile sets, chain IDs, deposit contract addresses, and other configuration errors.&lt;&#x2F;p&gt;
&lt;p&gt;For precompiles in particular there has been discussion about removing or replacing precompiles in future forks, so a full enumeration of precompiles will reflect removal.&lt;&#x2F;p&gt;
&lt;p&gt;Generally, if a configurable variable or constant causes a client to diverge at a fork—whether on Ethereum Mainnet, a testnet, a devnet, or a public rollup—that variable or constant is a candidate for inclusion in the reportable configuration.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;full-configs-instead-of-deltas&quot;&gt;Full Configs Instead of Deltas&lt;&#x2F;h3&gt;
&lt;p&gt;An initial design considered using a partial configuration for the &quot;next&quot; fork instead of a complete one. However, analysis of past events showed that some parameters causing divergence (e.g., the deposit contract) were introduced in earlier forks, with consensus failures occurring in later forks due to unrelated EIPs relying on those configurations. A partial &quot;next&quot; configuration hash would not have detected such errors.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative—embedding the prior fork’s hash in the next fork—would require defining rules for extracting differences and merging configurations, as well as specifying all prior fork configuration hashes. This would also complicate retroactively adding parameters (e.g., gas schedule constants and variables). The use of config hashes was also removed in a subsequent update.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nested-vs-flat-variables&quot;&gt;Nested vs. Flat Variables&lt;&#x2F;h3&gt;
&lt;p&gt;Nested structures are easier to read, while flat structures are easier to merge. Since this specification uses full configurations for the current and next forks, merging is unnecessary, making readability the priority.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;serving-data-not-specified-in-genesis-json&quot;&gt;Serving Data Not Specified in genesis.json&lt;&#x2F;h3&gt;
&lt;p&gt;Some reported values are specification-level constants, which many clients do not include in their configuration files. However, certain EIP constants (e.g., the deposit contract) have become variables in testnets, necessitating their inclusion.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;json-as-config-format&quot;&gt;JSON as Config Format&lt;&#x2F;h3&gt;
&lt;p&gt;JSON was chosen for its ubiquity, machine and human readability, and the existence of a standardized canonical form via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc8785&quot;&gt;RFC-8785&lt;&#x2F;a&gt;. YAML lacks a standard canonical form. No Ethereum software uses XML for configuration, and adopting it would increase every client&#x27;s library size. An invented format would be possible but would require definition and standardization within this specification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-no-configuration-hash&quot;&gt;Why no configuration hash&lt;&#x2F;h3&gt;
&lt;p&gt;Initial drafts included a hash of the configuration data for quick comparison. There was disagreement about the data format used to generate the hash (plain JSON, RLP, SSZ). Because tooling can effectively diff JSON objects by alphabetizing object keys, the hash is superfluous.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not alter previous behavior. Configurations prior to Cancun are non-standard, and clients sharing pre-Cancun configurations will produce non-standard results.&lt;&#x2F;p&gt;
&lt;p&gt;Clients supporting pre-Cancun forks MAY return partial or non-standard configurations but SHOULD strive to follow the spirit of the members specified for Cancun configurations. Full compliance is REQUIRED only for Cancun and later forks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sample-configs&quot;&gt;Sample Configs&lt;&#x2F;h3&gt;
&lt;p&gt;Hoodi Prague Config&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1742999832&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0929e24e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP2_TO_G2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000011&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP_TO_G1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000010&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_PAIRING_CHECK&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000bbddc7ce488642fb579f8b00f3a590007251&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000219ab540356cbb839cbe05303d7705fa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000f90827f1c53a10cb7a02335b175320002935&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000961ef480eb55e80d19ad83579a64c007002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;Hoodi Cancun Config&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3338477&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xbef71d30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h4 id=&quot;sample-json-rpc&quot;&gt;Sample JSON-RPC&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;with-future-fork-scheduled&quot;&gt;With Future Fork Scheduled&lt;&#x2F;h5&gt;
&lt;p&gt;The following RPC command, issued on Hoodi when Prague was scheduled but not activated:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;H&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Content-Type: application&#x2F;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{&amp;quot;jsonrpc&amp;quot;:&amp;quot;2.0&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;eth_config&amp;quot;,&amp;quot;id&amp;quot;:1}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; http:&#x2F;&#x2F;localhost:8545&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;would return (after formatting):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;jsonrpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;current&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3338477&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xbef71d30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;next&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1742999832&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0929e24e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP2_TO_G2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000011&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP_TO_G1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000010&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_PAIRING_CHECK&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000bbddc7ce488642fb579f8b00f3a590007251&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000219ab540356cbb839cbe05303d7705fa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000f90827f1c53a10cb7a02335b175320002935&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000961ef480eb55e80d19ad83579a64c007002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;last&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1742999832&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0929e24e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G1MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_G2MSM&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP2_TO_G2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000011&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_MAP_FP_TO_G1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000010&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLS12_PAIRING_CHECK&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000bbddc7ce488642fb579f8b00f3a590007251&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000219ab540356cbb839cbe05303d7705fa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000f90827f1c53a10cb7a02335b175320002935&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000961ef480eb55e80d19ad83579a64c007002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h5 id=&quot;without-future-fork-scheduled&quot;&gt;Without Future Fork Scheduled&lt;&#x2F;h5&gt;
&lt;p&gt;When no future forks are configured, the same RPC command would return:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;jsonrpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;current&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;activationTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3338477&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x88bb0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;forkId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xbef71d30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;precompiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BLAKE2F&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_ADD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000006&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_MUL&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000007&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BN254_PAIRING&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ECREC&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;KZG_POINT_EVALUATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MODEXP&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RIPEMD160&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000003&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;systemContracts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000f3df6d732807ef1319fb7b8bb8522d0beac02&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;next&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;last&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Exposure Risks&lt;&#x2F;strong&gt;: Incorrect configurations could leak operational details. Operators SHOULD restrict &lt;code&gt;eth_config&lt;&#x2F;code&gt; to trusted interfaces (e.g., local access or authenticated endpoints).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Dishonest Nodes&lt;&#x2F;strong&gt;: Clients may report false configurations. Peers or monitoring tools MAY cross-check &lt;code&gt;eth_config&lt;&#x2F;code&gt; outputs against known fork specifications or other nodes&#x27; responses to detect anomalies.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;DDoS Mitigation&lt;&#x2F;strong&gt;: Clients MAY cache configuration objects internally and rate-limit &lt;code&gt;eth_config&lt;&#x2F;code&gt; requests to prevent resource exhaustion. Implementations MAY impose a minimum response interval (e.g., 1 second).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>HD wallet In Treasury Management</title>
        <published>2025-03-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Xiaoyu Liu</name><uri>https://github.com/elizabethxiaoyu</uri><email>jiushi.lxy@antgroup.com</email>
	</author>
	
	<author>
		<name>Yuxiang Fu</name><uri>https://github.com/tmac4096</uri><email>kunfu.fyx@antgroup.com</email>
	</author>
	
	<author>
		<name>Yanyi Liang</name><email>eason.lyy@antgroup.com</email>
	</author>
	
	<author>
		<name>Hao Zou</name><uri>https://github.com/BruceZH0915</uri><email>situ.zh@antgroup.com</email>
	</author>
	
	<author>
		<name>Siyuan Zheng</name><uri>https://github.com/andrewcoder666</uri><email>zhengsiyuan.zsy@antgroup.com</email>
	</author>
	
	<author>
		<name>yuanshanhshan</name><uri>https://github.com/xunayuan</uri><email>yuanshanshan.yss@antgroup.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7908/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/new-erc-deterministic-account-hierarchy-in-treasury-management/23073" />
        

        <id>https://wg-eips.ritovision.com/7908/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7908"
            label="ERC-7908" />
        

        
        

        
        <summary type="html">Hierarchical deterministic (HD) wallets for treasury systems, isolating entities via cryptographic key paths.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7908/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal aims to provide a standardized method for on-chain treasury management of institutional assets, ensuring secure private key generation, hierarchical management, and departmental permission isolation while supporting asset security and transaction efficiency in multi-chain environments. By defining a unified derivation path and security mechanisms, this proposal offers an efficient and secure solution for treasury management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the rapid development of blockchain and DeFi, secure management of on-chain assets has become critical. Traditional private key management struggles to meet the security demands of large organizations in complex scenarios, where hierarchical key management, permission controls, and multi-signature mechanisms are essential. This proposal provides a standardized solution for institutional treasury management, ensuring asset security and transaction efficiency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2119&quot;&gt;RFC 2119&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc8174&quot;&gt;RFC 8174&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;derivation-path&quot;&gt;Derivation Path&lt;&#x2F;h3&gt;
&lt;p&gt;For secure on-chain treasury account key management, implementations MUST use the following hierarchical
deterministic (HD) path:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;latex&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m&#x2F;44&amp;#39;&#x2F;60&amp;#39;&#x2F;entity_id&amp;#39; &#x2F; department_id&amp;#39; &#x2F; account_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Path Components:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Master Key (&lt;&#x2F;strong&gt;&lt;code&gt;m&lt;&#x2F;code&gt;&lt;strong&gt;)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL represent the root HD wallet private key.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;0278bf3d7111bab8f0ef8dd08f16fd7b5ac6cbd6&#x2F;bip-0044.mediawiki&quot;&gt;BIP 44&lt;&#x2F;a&gt; Compliance Layer (&lt;code&gt;44&#x27;&lt;&#x2F;code&gt;)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST use &lt;code&gt;44&#x27;&lt;&#x2F;code&gt; (hardened) to indicate BIP 44 compliance.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Coin Type Layer ( &lt;code&gt;60&#x27;&lt;&#x2F;code&gt; )&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL use &lt;code&gt;60&#x27;&lt;&#x2F;code&gt; (hardened) for Ethereum and EVM-compatible chains.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Entity Identifier ( &lt;code&gt;entity_id&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST be derived by hashing the subsidiary name into a hardened index.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT reuse the same &lt;code&gt;entity_id&#x27;&lt;&#x2F;code&gt; across distinct subsidiaries.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Department Identifier (&lt;&#x2F;strong&gt;&lt;code&gt;department_id&#x27;&lt;&#x2F;code&gt;&lt;strong&gt;)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL be derived by hashing the department name into a hardened index.&lt;&#x2F;li&gt;
&lt;li&gt;MUST isolate keys between departments via hardened derivation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Account Index (&lt;&#x2F;strong&gt;&lt;code&gt;account_index&lt;&#x2F;code&gt;&lt;strong&gt;)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST use non-hardened derivation to allow unified account management.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Note on BIP 44 Adaptation&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The BIP 44 &lt;code&gt;change&lt;&#x2F;code&gt; layer SHOULD be omitted for Ethereum&#x2F;EVMs due to their account model (not UTXO).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;hash-conversion&quot;&gt;Hash Conversion&lt;&#x2F;h3&gt;
&lt;p&gt;To derive &lt;code&gt;entity_id&lt;&#x2F;code&gt; and &lt;code&gt;department_id&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Entity Index Calculation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL compute &lt;code&gt;entity_id&lt;&#x2F;code&gt; as:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entity_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ENTITY:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;entity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;entity_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;entity_hash&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;80000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2^31 ≤ index &amp;lt; 2^32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Department Index Calculation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST compute &lt;code&gt;department_id&lt;&#x2F;code&gt; as:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dept_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DEPT:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;entity_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;department&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;dept_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dept_hash&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;80000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2^31 ≤ index &amp;lt; 2^32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Output Constraints&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generated indices MUST be integers in &lt;code&gt;[2^31, 2^32-1]&lt;&#x2F;code&gt; to enforce hardened derivation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;extended-path-for-role-based-access&quot;&gt;Extended Path for Role-Based Access&lt;&#x2F;h3&gt;
&lt;p&gt;For finer access control (e.g., roles within departments):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;latex&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m&#x2F;60&amp;#39;&#x2F;entity_id&amp;#39; &#x2F; department_id&amp;#39; &#x2F;role_id&amp;#39;&#x2F; account_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Role Identifier (&lt;&#x2F;strong&gt;&lt;code&gt;role_id&#x27;&lt;&#x2F;code&gt;&lt;strong&gt;)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHOULD use hardened derivation to isolate role-specific keys.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Compatibility Note&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Omitting the &lt;code&gt;44&#x27;&lt;&#x2F;code&gt; layer MAY cause incompatibility with standard wallets (e.g., MetaMask).&lt;&#x2F;li&gt;
&lt;li&gt;Integrations with such wallets MUST implement custom plugins to handle this deviation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;simplified-path-for-smaller-entities&quot;&gt;Simplified Path for Smaller Entities&lt;&#x2F;h3&gt;
&lt;p&gt;For entities without subsidiaries:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;latex&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m&#x2F;44&amp;#39;&#x2F;60&amp;#39; &#x2F; department_id&amp;#39; &#x2F;0&#x2F; account_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Compatibility Guarantee&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This structure SHOULD ensure compatibility with mainstream BIP 44 wallets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;key-derivation-algorithm&quot;&gt;Key Derivation Algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations MUST adhere to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;latex&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;E = Map&amp;lt;entity, List&amp;lt;Department&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;n = Layer2 curve order&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path = m&#x2F;44&amp;#39;&#x2F;60&amp;#39;&#x2F;entity_id&amp;#39; &#x2F; department_id&amp;#39; &#x2F; account_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BIP32() = Official BIP-0032 derivation function on secp256k1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hash = SHA256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root_key = BIP32(path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for each E:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	key = hash(root_key|hierarchical_hash_to_index(entity,department))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	return key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Cryptographic Requirements&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;86b29c5d81c755133114486c19a271c34087fc81&#x2F;bip-0032.mediawiki&quot;&gt;BIP 32&lt;&#x2F;a&gt; with &lt;code&gt;secp256k1&lt;&#x2F;code&gt; for HD derivation.&lt;&#x2F;li&gt;
&lt;li&gt;MUST concatenate hashes with root keys to prevent cross-layer key leakage.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;compatibility-considerations&quot;&gt;&lt;strong&gt;Compatibility Considerations&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This specification is inspired by BIP 44 (&lt;code&gt;m&#x2F;purpose&#x27;&#x2F;coin_type&#x27;&#x2F;account&#x27;&#x2F;change&#x2F;address_index&lt;&#x2F;code&gt;), but:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SHALL NOT use the &lt;code&gt;change&lt;&#x2F;code&gt; layer for Ethereum-based systems.&lt;&#x2F;li&gt;
&lt;li&gt;MAY extend the hierarchy beyond BIP 44’s 5-layer structure for organizational needs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The scenarios for which the proposal applies are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Company and Department Isolation&lt;&#x2F;strong&gt;: Different subsidiaries within the group, as well as different departments within each subsidiary, can create isolated on-chain accounts. Enhanced derivation is used to isolate exposure risks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Group Unified Management Authority&lt;&#x2F;strong&gt;: The group administrator holds the master private key, which can derive all subsidiary private keys, granting the highest authority to view and initiate transactions across the entire group, facilitating unified management by the group administrator.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Shared Department Private Key&lt;&#x2F;strong&gt;: If subsidiary A&#x27;s administrator, Alice, needs to share accounts under subsidiary A with a new administrator, Bob, she only needs to share the master private key of subsidiary A. Accounts from various departments can then be derived from this key.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Shared Audit Public Key&lt;&#x2F;strong&gt;: If the audit department needs to audit transactions under a specific department, the extended public key of the specified department can be shared with the audit department. Through this extended public key, all subordinate public keys under the department can be derived, allowing the audit department to track all transactions associated with these public key addresses.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard complies with BIP 39, BIP 32, and BIP 44.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Secure Treasury Management System&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Enterprise-grade hierarchical deterministic wallet implementation compliant with BIP-44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; hashlib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Dict&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; bip32utils&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; BIP32Key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; eth_account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&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 class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; mnemonic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Mnemonic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add BIP39 support&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Configure logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;logging&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;basicConfig&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;logging&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;INFO&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;logger&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; logging&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;getLogger&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;TreasurySystem&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TreasurySystem&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; mnemonic&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Initialize the treasury system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        :param mnemonic: BIP-39 mnemonic (12&#x2F;24 words)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt; Mnemonic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;english&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mnemonic&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Invalid BIP-39 mnemonic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Generate seed using standard BIP-39&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Mnemonic&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_seed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mnemonic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; passphrase&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;root_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BIP32Key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fromEntropy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;seed&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        logger&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;info&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Treasury system initialized. Master key fingerprint: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;                  self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;root_key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Fingerprint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _hierarchical_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;entity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; department&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Hierarchical hash calculation (compliant with proposal spec)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Returns: (entity_index, department_index)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Entity hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        entity_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hashlib&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ENTITY:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;entity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&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&gt;        entity_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;entity_hash&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;80000000&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Department hash (chained)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dept_input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DEPT:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;entity_hash&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;department&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encode&lt;&#x2F;span&gt;&lt;span&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&gt;        dept_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hashlib&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dept_input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&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&gt;        dept_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dept_hash&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;80000000&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; entity_index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; dept_index&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _derive_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; path&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; BIP32Key&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;General key derivation method&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        current_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;root_key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Invalid derivation index type: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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&gt;            current_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; current_key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ChildKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; current_key&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; generate_account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; entity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; department&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-parameter z-function&quot;&gt;                        account_idx&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Dict&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Generate department account (BIP44 5-layer structure)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Path: m&#x2F;44&amp;#39;&#x2F;60&amp;#39;&#x2F;entity&amp;#39;&#x2F;dept&amp;#39;&#x2F;account_idx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_hierarchical_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;entity&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; department&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; BIP-44 standard path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        derivation_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000002C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 44&amp;#39; (hardened)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000003C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 60&amp;#39; (Ethereum)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; entity_index (hardened)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            d_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; department_index (hardened)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            account_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address index&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_derive_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;derivation_path&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        priv_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;PrivateKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;m&#x2F;44&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&#x2F;60&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;e_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;account_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;private_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; priv_key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Warning: Never expose this in production&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Account&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;priv_key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;address&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_audit_xpub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; entity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; department&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Retrieve department-level extended public key (for auditing)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Path: m&#x2F;44&amp;#39;&#x2F;60&amp;#39;&#x2F;entity&amp;#39;&#x2F;dept&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_hierarchical_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;entity&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; department&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000002C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 44&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000003C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 60&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; entity&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; dept&amp;#39;&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_derive_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ExtendedKey&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_dept_xprv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; entity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; department&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Get department-level extended private key (strictly controlled)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        Path: m&#x2F;44&amp;#39;&#x2F;60&amp;#39;&#x2F;entity&amp;#39;&#x2F;dept&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_hierarchical_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;entity&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; department&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000002C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 44&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8000003C&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 60&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            e_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; entity&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            d_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; dept&amp;#39;&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_derive_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ExtendedKey&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; derive_addresses_from_xpub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;xpub&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; count&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Derive addresses from extended public key (audit use)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        audit_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BIP32Key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fromExtendedKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;xpub&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Account&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_key&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                audit_key&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&gt;ChildKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address index&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&gt;PrivateKey&lt;&#x2F;span&gt;&lt;span&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&gt;            )&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;count&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&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 class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt; __name__&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;__main__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example usage (remove private key printing in production)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Use standard mnemonic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mnemo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Mnemonic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;english&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;        mnemonic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mnemo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;generate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;strength&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        treasury&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; TreasurySystem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mnemonic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mnemonic: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;mnemonic&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=== Finance Department Account Generation ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;        finance_acc1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; treasury&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;generate_account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GroupA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Finance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        finance_acc2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; treasury&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;generate_account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GroupA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Finance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account1 path: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc1&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account1 address: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc1&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account1 private key: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc1&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;private_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account2 path: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc2&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account2 address: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc2&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account2 private key: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;finance_acc2&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;private_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=== Audit Verification Test===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;        audit_xpub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; treasury&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_audit_xpub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GroupA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Finance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Audit xpub: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;audit_xpub&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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&gt;        audit_addresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; TreasurySystem&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;derive_addresses_from_xpub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;audit_xpub&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Audit-derived addresses: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;audit_addresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; finance_acc1&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; audit_addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Audit verification failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; finance_acc2&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; audit_addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Audit verification failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;✅ Audit verification successful&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=== Department Isolation Test ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;        other_dept_acc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; treasury&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;generate_account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GroupA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Audit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account3 path: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;other_dept_acc&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account3 address: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;other_dept_acc&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; other_dept_acc&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; audit_addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Isolation breach&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;✅ Department isolation effective&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=== Department Private Key Sharing Test ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets the department layer extension private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dept_xprv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; treasury&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_audit_xpub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GroupA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Finance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xpub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xprv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 实际应通过专用方法获取&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Fiance xprv: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;dept_xprv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Derive the account private key from the extension private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dept_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BIP32Key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fromExtendedKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dept_xprv&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        derived_acc0_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dept_key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ChildKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;PrivateKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&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&gt;        derived_acc1_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dept_key&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ChildKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;PrivateKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Fiance derived_acc0_key: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;derived_acc0_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Fiance derived_acc1_key: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;derived_acc1_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify the private key derivation capability&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; derived_acc0_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; finance_acc1&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;private_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account 0 private key derivation failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; derived_acc1_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; finance_acc2&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;private_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Account 1 private key derivation failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;✅ Private key derivation from department xprv successful&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        logger&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;System error: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; exc_info&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;run script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pip&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bip32utils&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; eth_account&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 class=&quot;z-entity z-name&quot;&gt;python&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; stms.py&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;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7908&#x2F;.&#x2F;assets&#x2F;img.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;For treasury managers, hierarchical deterministic wallet management is more convenient, but it requires additional consideration of protective measures for the master key, such as schemes for splitting and storing mnemonic phrases or master keys.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blob Parameter Only Hardforks</title>
        <published>2025-02-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mark Mackey</name><uri>https://github.com/ethDreamer</uri>
	</author>
	
	<author>
		<name>Raúl Kripalani</name><uri>https://github.com/raulk</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7892/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7892-blob-parameter-only-hardforks/23018" />
        

        <id>https://wg-eips.ritovision.com/7892/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        

        
        <category
            term="tag:eip:7892"
            label="EIP-7892" />
        

        
        

        
        <summary type="html">Defines a mechanism for scaling Ethereum’s blob capacity via specialized hard forks that modify only blob-related parameters.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7892/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces &lt;strong&gt;Blob Parameter Only (BPO) Hardforks&lt;&#x2F;strong&gt;, a lightweight mechanism for incrementally scaling Ethereum’s blob capacity through targeted hard forks that modify only blob-related parameters: &lt;code&gt;target&lt;&#x2F;code&gt;, &lt;code&gt;max&lt;&#x2F;code&gt;, and &lt;code&gt;baseFeeUpdateFraction&lt;&#x2F;code&gt;. Unlike traditional hard forks, which require extensive coordination and introduce broader protocol changes, BPO forks enable rapid, low-overhead scaling of blob capacity in response to &lt;strong&gt;real-world demand and network conditions&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum&#x27;s scaling strategy relies on Layer 2 (L2) solutions for transaction execution while using Ethereum as a &lt;strong&gt;data availability (DA) layer&lt;&#x2F;strong&gt;. However, the demand for DA has increased rapidly, and the current approach of only modifying blob parameters in large, infrequent hard forks is &lt;strong&gt;not agile enough&lt;&#x2F;strong&gt; to keep up with L2 growth.&lt;&#x2F;p&gt;
&lt;p&gt;The key motivations for BPO forks are as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Continuous Scaling&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;L2 DA demand is growing rapidly, leading to ongoing saturation of blob capacity.&lt;&#x2F;li&gt;
&lt;li&gt;Large, infrequent blob parameter changes create high costs and inefficiencies.&lt;&#x2F;li&gt;
&lt;li&gt;BPO forks allow for more frequent, safer capacity increases.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced Operational Overhead&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Performance improvements and further testing will continue to unlock additional capacity.&lt;&#x2F;li&gt;
&lt;li&gt;It is desirable to reduce the time between core devs agreeing on a parameter increase and its effective deployment.&lt;&#x2F;li&gt;
&lt;li&gt;Full Ethereum hard forks require significant coordination, testing, and upgrade efforts across clients.&lt;&#x2F;li&gt;
&lt;li&gt;By isolating blob parameter changes, BPO forks reduce the complexity of upgrades.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enhanced Stability with New Scaling Technologies&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Major scaling upgrades introduce uncertainty in optimal blob limits.&lt;&#x2F;li&gt;
&lt;li&gt;Rather than forcing core developers to accept a suboptimal tradeoff between stability and capacity, BPO forks allow developers to safely increase parameters after observing mainnet performance and stability.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Predictable Upgrades for Builders&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Builders and L2s require confidence that Ethereum will continuously scale to support their needs.&lt;&#x2F;li&gt;
&lt;li&gt;A structured BPO framework provides predictability, allowing rollups to commit to Ethereum over alternative DA solutions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definition&quot;&gt;Definition&lt;&#x2F;h3&gt;
&lt;p&gt;BPO hardforks are defined as protocol upgrades that modify only blob-related parameters through configuration, without requiring any client-side code changes. The new parameters take effect immediately at the specified activation time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blob-schedule-configuration&quot;&gt;Blob schedule configuration&lt;&#x2F;h3&gt;
&lt;p&gt;The following protocol parameters are now managed by the blob schedule configuration:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blob Target (&lt;code&gt;target&lt;&#x2F;code&gt;)&lt;&#x2F;strong&gt;: The expected number of blobs per block.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Blob Limit (&lt;code&gt;max&lt;&#x2F;code&gt;)&lt;&#x2F;strong&gt;: The maximum number of blobs per block.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Blob Base Fee Update Fraction (&lt;code&gt;baseFeeUpdateFraction&lt;&#x2F;code&gt;)&lt;&#x2F;strong&gt;: Determines how blob gas pricing adjusts per block.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To ensure consistency, when a regular hardfork changes any of these parameters, it MUST do so by adding an entry to the blob schedule configuration.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-layer-configuration&quot;&gt;Execution layer configuration&lt;&#x2F;h3&gt;
&lt;p&gt;To facilitate these changes on the execution layer, each fork in the &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; object defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7840&#x2F;&quot;&gt;EIP-7840&lt;&#x2F;a&gt; is linked to an activation timestamp via a top-level &lt;code&gt;&amp;lt;fork_name&amp;gt;Time&lt;&#x2F;code&gt; field, which holds the Unix timestamp of the activation slot as a JSON number. BPO forks SHOULD be named using the convention &lt;code&gt;bpo&amp;lt;index&amp;gt;&lt;&#x2F;code&gt;, where &lt;code&gt;&amp;lt;index&amp;gt;&lt;&#x2F;code&gt; starts at &lt;code&gt;1&lt;&#x2F;code&gt;. Left padding is unnecessary since these labels are not subject to lexicographic sorting. Activation timestamps are required only for forks that occur &lt;strong&gt;after&lt;&#x2F;strong&gt; Prague.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;cancun&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3338477&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prague&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;osaka&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bpo1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8346193&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bpo2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11684671&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;cancunTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;pragueTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;osakaTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1747387400&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bpo1Time&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1757387400&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bpo2Time&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1767387784&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;Since there is no backporting, the values for &lt;code&gt;cancunTime&lt;&#x2F;code&gt; and &lt;code&gt;pragueTime&lt;&#x2F;code&gt; are set to 0. It should also be noted that the other parameters and schedules above are purely illustrative. Actual values and schedules are beyond the scope of this specification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blob-base-fee-computations&quot;&gt;Blob base fee computations&lt;&#x2F;h3&gt;
&lt;p&gt;We modify the functions &lt;code&gt;get_base_fee_per_blob_gas&lt;&#x2F;code&gt; and &lt;code&gt;calc_excess_blob_gas&lt;&#x2F;code&gt; defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; to explicitly use the blob schedule.
In line with how updating &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt; was handled in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7691&#x2F;&quot;&gt;EIP-7691&lt;&#x2F;a&gt;, the functions use the &lt;em&gt;current&lt;&#x2F;em&gt; block&#x27;s blob schedule.
Moreover, &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; is removed and replaced with &lt;code&gt;GAS_PER_BLOB * blob_schedule.target&lt;&#x2F;code&gt;, as it is now redundant.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BlobSchedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   target&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; U64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;   max&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; U64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   base_fee_update_fraction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Uint&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 class=&quot;z-storage z-type&quot;&gt; def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calc_excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BlobSchedule&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    target_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; target_blob_gas&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; target_blob_gas&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;header&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; BlobSchedule&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        MIN_BASE_FEE_PER_BLOB_GAS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_update_fraction&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;h3 id=&quot;consensus-layer-configuration&quot;&gt;Consensus layer configuration&lt;&#x2F;h3&gt;
&lt;p&gt;A new &lt;code&gt;BLOB_SCHEDULE&lt;&#x2F;code&gt; field is added to consensus layer configuration, containing a sequence of entries representing blob parameter changes &lt;strong&gt;after&lt;&#x2F;strong&gt; &lt;code&gt;ELECTRA_FORK_EPOCH&lt;&#x2F;code&gt;. There exists one entry per fork that changes blob parameters, whether it is a regular or a Blob-Parameter-Only fork.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;LOB_SCHEDULE&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; E&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;POCH&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 400000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A future anonymous BPO fork&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    M&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;AX_BLOBS_PER_BLOCK&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&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 class=&quot;z-entity z-name z-tag&quot;&gt; E&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;POCH&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 420000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A future anonymous BPO fork&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    M&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;AX_BLOBS_PER_BLOCK&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The parameters and schedules above are purely illustrative. Actual values and schedules are beyond the scope of this specification.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Requirements:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Execution and consensus clients &lt;strong&gt;MUST&lt;&#x2F;strong&gt; share consistent BPO fork schedules.&lt;&#x2F;li&gt;
&lt;li&gt;The slot number in the EL&#x27;s &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; align with the start of the epoch specified in the consensus layer configuration.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;max&lt;&#x2F;code&gt; field in the EL&#x27;s &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; equal the &lt;code&gt;MAX_BLOBS_PER_BLOCK&lt;&#x2F;code&gt; value in the consensus layer configuration.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;modified-compute-fork-digest&quot;&gt;Modified &lt;code&gt;compute_fork_digest&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;compute_fork_digest&lt;&#x2F;code&gt; helper is updated to account for BPO forks:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BlobScheduleEntry&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Epoch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   max_blobs_per_block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Aligning with the type of MAX_BLOBS_PER_BLOCK&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compute_fork_digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;  current_version&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unchanged; refers to the baseline hardfork atop which the blob schedule is applied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;  genesis_validators_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;  current_epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;           #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;  blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;BlobScheduleEntry&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New&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&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ForkDigest&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Return the 4-byte fork digest for the ``current_version`` and ``genesis_validators_root``,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    bitmasking blob parameters after ``ELECTRA_FORK_VERSION``.&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 class=&quot;z-string&quot;&gt;    This is a digest primarily used for domain separation on the p2p layer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    4-bytes suffices for practical separation of forks&#x2F;chains.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base_digest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; compute_fork_data_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;current_version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; genesis_validators_root&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find the blob parameters applicable to this epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sorted_schedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;blob_schedule&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; e&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; reverse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    blob_params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; sorted_schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; current_epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; entry&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blob_params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        break&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This check enables us to roll out the BPO mechanism without a concurrent parameter change.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; blob_params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt; ForkDigest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;base_digest&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Safely bitmask blob parameters into the digest.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; blob_params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_blobs_per_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;FFFFFFFF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blob_params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_blobs_per_block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;    masked_digest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;base_digest&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ForkDigest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;masked_digest&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;p2p-networking&quot;&gt;P2P Networking&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;enr&quot;&gt;ENR&lt;&#x2F;h4&gt;
&lt;p&gt;In the consensus layer, ENRs are extended with an additional entry &lt;code&gt;nfd&lt;&#x2F;code&gt;, short for &quot;next fork digest&quot;. This field communicates the digest of the next scheduled fork, regardless of whether it is a regular or BPO fork. This approach is preferred over encoding BPO-specific parameters because it is agnostic to specific use cases and offers greater long-term flexibility.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Key&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;nfd&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;SSZ Bytes4 &lt;code&gt;ForkDigest&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;When discovering and interfacing with peers, nodes MUST evaluate &lt;code&gt;nfd&lt;&#x2F;code&gt; alongside their existing consideration of the &lt;code&gt;ENRForkID::next_*&lt;&#x2F;code&gt; fields under the &lt;code&gt;eth2&lt;&#x2F;code&gt; key, to form a more accurate view of the peer&#x27;s intended next fork.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;status-req-resp&quot;&gt;&lt;code&gt;Status&lt;&#x2F;code&gt; req&#x2F;resp&lt;&#x2F;h4&gt;
&lt;p&gt;No changes are needed in this interaction, but it is noted that the response payload must correctly contain the updated &lt;code&gt;fork_digest&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;gossip-topics&quot;&gt;Gossip topics&lt;&#x2F;h4&gt;
&lt;p&gt;No changes are required to topic structure or configuration. However, all topics will automatically rotate at a BPO fork due to changes in their &lt;code&gt;ForkDigestValue&lt;&#x2F;code&gt; component.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-not-just-use-regular-hardforks&quot;&gt;Why not just use regular hardforks?&lt;&#x2F;h3&gt;
&lt;p&gt;Full hard forks require extensive coordination, testing, and implementation changes beyond parameter adjustments. For example, in Lighthouse, a typical hard fork implementation requires thousands of lines of boilerplate before any protocol changes occur. BPO forks streamline this process by avoiding the need for this boilerplate code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-specify-parameters-in-the-node-configuration-instead-of-code&quot;&gt;Why specify parameters in the node configuration instead of code?&lt;&#x2F;h3&gt;
&lt;p&gt;Allowing blob parameters to be configured externally enables rapid experimentation, testing, and adjustments without requiring code changes across client implementations. Testing teams can investigate different parameters with minimal involvement from client implementers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-create-an-on-chain-voting-mechanism-for-blob-parameters&quot;&gt;Why not create an on-chain voting mechanism for blob parameters?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Ethereum&#x27;s recent gas limit increase to 36M took nearly a year to coordinate&lt;&#x2F;li&gt;
&lt;li&gt;Blob capacity is a rapidly evolving, moving target that the wider staking community is not currently well equipped to track&lt;&#x2F;li&gt;
&lt;li&gt;An on-chain mechanism would require much more extensive code changes, testing cycles, and debates about governance structures.&lt;&#x2F;li&gt;
&lt;li&gt;BPO forks provide a simpler, more predictable approach while leaving room for future on-chain voting mechanisms when blob capacity stabilizes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;BPO forks introduce no backwards compatibility concerns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security risks have been identified.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ModExp Gas Cost Increase</title>
        <published>2025-02-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Marcin Sobczak</name><uri>https://github.com/marcindsobczak</uri>
	</author>
	
	<author>
		<name>Marek Moraczyński</name><uri>https://github.com/MarekM25</uri>
	</author>
	
	<author>
		<name>Marcos Maceo</name><uri>https://github.com/stdevMac</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7883/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7883-modexp-gas-cost-increase/22841" />
        

        <id>https://wg-eips.ritovision.com/7883/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7883"
            label="EIP-7883" />
        

        
        

        
        <summary type="html">Increases cost of ModExp precompile</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7883/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is modifying the &lt;code&gt;ModExp&lt;&#x2F;code&gt; precompile pricing algorithm introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2565&#x2F;&quot;&gt;EIP-2565&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently the &lt;code&gt;ModExp&lt;&#x2F;code&gt; precompile is underpriced in certain scenarios relative to its resource consumption. By adjusting the pricing formula, this EIP aims to address these discrepancies, making &lt;code&gt;ModExp&lt;&#x2F;code&gt; sufficiently efficient to enable potential increases in the block gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Upon activation of this EIP, the gas cost of calling the precompile at address &lt;code&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;code&gt; will be calculated as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def calculate_multiplication_complexity(base_length, modulus_length):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    max_length = max(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    words = math.ceil(max_length &#x2F; 8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multiplication_complexity = 16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if max_length &amp;gt; 32: multiplication_complexity = 2 * words**2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return multiplication_complexity&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;def calculate_iteration_count(exponent_length, exponent):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    iteration_count = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if exponent_length &amp;lt;= 32 and exponent == 0: iteration_count = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;lt;= 32: iteration_count = exponent.bit_length() - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;gt; 32: iteration_count = (16 * (exponent_length - 32)) + ((exponent &amp;amp; (2**256 - 1)).bit_length() - 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(iteration_count, 1)&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;def calculate_gas_cost(base_length, modulus_length, exponent_length, exponent):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multiplication_complexity = calculate_multiplication_complexity(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    iteration_count = calculate_iteration_count(exponent_length, exponent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(500, math.floor(multiplication_complexity * iteration_count))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The specific changes from the algorithm defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2565&#x2F;&quot;&gt;EIP-2565&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-increased-minimal-and-general-price&quot;&gt;1. Increased minimal and general price&lt;&#x2F;h3&gt;
&lt;p&gt;The gas cost calculation is modified from:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(200, math.floor(multiplication_complexity * iteration_count &#x2F; 3))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(500, math.floor(multiplication_complexity * iteration_count))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This change increases the minimum gas cost from 200 to 500 and triples the general cost by removing the division by 3.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-increase-cost-for-exponents-larger-than-32-bytes&quot;&gt;2. Increase cost for exponents larger than 32 bytes&lt;&#x2F;h3&gt;
&lt;p&gt;The gas cost calculation is modified from:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;gt; 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent &amp;amp; (2**256 - 1)).bit_length() - 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;gt; 32: iteration_count = (16 * (exponent_length - 32)) + ((exponent &amp;amp; (2**256 - 1)).bit_length() - 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The multiplier for exponents larger than 32 bytes is increased from 8 to 16, doubling its impact.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-assume-the-minimal-base-modulus-length-to-be-32-and-increase-the-cost-when-it-is-larger-than-32-bytes&quot;&gt;3. Assume the minimal base &#x2F; modulus length to be 32 and increase the cost when it is larger than 32 bytes&lt;&#x2F;h3&gt;
&lt;p&gt;The gas cost calculation is modified from:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def calculate_multiplication_complexity(base_length, modulus_length):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    max_length = max(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    words = math.ceil(max_length &#x2F; 8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return words**2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def calculate_multiplication_complexity(base_length, modulus_length):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    max_length = max(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    words = math.ceil(max_length &#x2F; 8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multiplication_complexity = 16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if max_length &amp;gt; 32: multiplication_complexity = 2 * words**2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return multiplication_complexity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This change introduces a minimal multiplication complexity of 16 and doubles the complexity if the base or modulus length exceeds 32 bytes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Benchmarking the &lt;code&gt;ModExp&lt;&#x2F;code&gt; precompile revealed several scenarios where its gas cost was significantly underestimated. Pricing adjustments are designed to rectify underpriced edge cases by modifying the existing &lt;code&gt;ModExp&lt;&#x2F;code&gt; pricing formula parameters. Specifically, the minimum cost for &lt;code&gt;ModExp&lt;&#x2F;code&gt; will rise from 200 to 500 (a 150% increase), the general cost will triple (a 200% increase), a minimum base&#x2F;modulus length of 32 bytes will be assumed and the cost will scale more aggressively when the base, modulus, or exponent exceed 32 bytes. These modifications aim to ensure that the &lt;code&gt;ModExp&lt;&#x2F;code&gt; precompile&#x27;s performance, even in its most resource-intensive edge cases across all execution layer clients, no longer impedes potential increases to the block gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a backwards-incompatible change. However, similar gas repricings have occurred multiple times in the Ethereum ecosystem, and their effects are well understood.&lt;&#x2F;p&gt;
&lt;p&gt;An empirical analysis of this proposal is available &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7883&#x2F;assets&#x2F;call_analysis&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;, with a separate breakdown by affected entities provided &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7883&#x2F;assets&#x2F;entity_analysis&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The most common usages (approximately 99.69% of historical &lt;code&gt;Modexp&lt;&#x2F;code&gt; calls as of January 4th, 2025) will experience either a 150% increase (from 200 to 500 gas) or a 200% increase (tripling from approximately 1360 gas).
No changes are made to the underlying interface or arithmetic algorithms, allowing existing test vectors to be reused. The table below presents the updated gas costs for these test vectors:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Test Case&lt;&#x2F;th&gt;&lt;th&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2565&#x2F;&quot;&gt;EIP-2565&lt;&#x2F;a&gt; Pricing&lt;&#x2F;th&gt;&lt;th&gt;EIP-7883 Pricing&lt;&#x2F;th&gt;&lt;th&gt;Increase&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_square&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;500&lt;&#x2F;td&gt;&lt;td&gt;150%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_qube&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;500&lt;&#x2F;td&gt;&lt;td&gt;150%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;td&gt;2048&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_square&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;512&lt;&#x2F;td&gt;&lt;td&gt;156%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_qube&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;512&lt;&#x2F;td&gt;&lt;td&gt;156%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;td&gt;8192&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_square&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;td&gt;2048&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_qube&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;td&gt;2048&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;td&gt;32768&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_square&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;td&gt;8192&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_qube&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;td&gt;8192&lt;&#x2F;td&gt;&lt;td&gt;501%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;21845&lt;&#x2F;td&gt;&lt;td&gt;131072&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_square&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;td&gt;32768&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_qube&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;td&gt;32768&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;87381&lt;&#x2F;td&gt;&lt;td&gt;524288&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marius_1_even&lt;&#x2F;td&gt;&lt;td&gt;2057&lt;&#x2F;td&gt;&lt;td&gt;45296&lt;&#x2F;td&gt;&lt;td&gt;2102%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_guido_1_even&lt;&#x2F;td&gt;&lt;td&gt;2298&lt;&#x2F;td&gt;&lt;td&gt;51136&lt;&#x2F;td&gt;&lt;td&gt;2125%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_guido_2_even&lt;&#x2F;td&gt;&lt;td&gt;2300&lt;&#x2F;td&gt;&lt;td&gt;51152&lt;&#x2F;td&gt;&lt;td&gt;2124%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_guido_3_even&lt;&#x2F;td&gt;&lt;td&gt;5400&lt;&#x2F;td&gt;&lt;td&gt;32400&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_guido_4_even&lt;&#x2F;td&gt;&lt;td&gt;1026&lt;&#x2F;td&gt;&lt;td&gt;94448&lt;&#x2F;td&gt;&lt;td&gt;9105%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_1_base_heavy&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;1152&lt;&#x2F;td&gt;&lt;td&gt;476%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_1_exp_heavy&lt;&#x2F;td&gt;&lt;td&gt;215&lt;&#x2F;td&gt;&lt;td&gt;16624&lt;&#x2F;td&gt;&lt;td&gt;7632%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_1_balanced&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;1200&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_2_base_heavy&lt;&#x2F;td&gt;&lt;td&gt;867&lt;&#x2F;td&gt;&lt;td&gt;5202&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_2_exp_heavy&lt;&#x2F;td&gt;&lt;td&gt;852&lt;&#x2F;td&gt;&lt;td&gt;16368&lt;&#x2F;td&gt;&lt;td&gt;1821%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_2_balanced&lt;&#x2F;td&gt;&lt;td&gt;996&lt;&#x2F;td&gt;&lt;td&gt;5978&lt;&#x2F;td&gt;&lt;td&gt;500%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_3_base_heavy&lt;&#x2F;td&gt;&lt;td&gt;677&lt;&#x2F;td&gt;&lt;td&gt;2032&lt;&#x2F;td&gt;&lt;td&gt;200%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_3_exp_heavy&lt;&#x2F;td&gt;&lt;td&gt;765&lt;&#x2F;td&gt;&lt;td&gt;4080&lt;&#x2F;td&gt;&lt;td&gt;433%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_marcin_3_balanced&lt;&#x2F;td&gt;&lt;td&gt;1360&lt;&#x2F;td&gt;&lt;td&gt;4080&lt;&#x2F;td&gt;&lt;td&gt;200%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce any new functionality or make existing operations cheaper, therefore there are no direct security concerns related to new attack vectors or reduced costs. The primary security consideration for this EIP is the potential for &lt;code&gt;ModExp&lt;&#x2F;code&gt; scenarios to be overpriced, though this is deemed a lesser risk compared to the current underpricing issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Bequeathable Contracts</title>
        <published>2025-02-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Wamith Mockbill</name><uri>https://github.com/wamith</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7878/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/new-erc-bequeathable-tokens-a-standard-to-allow-tokens-to-be-inherited-after-the-owners-death/22755" />
        

        <id>https://wg-eips.ritovision.com/7878/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7878"
            label="ERC-7878" />
        

        
        

        
        <summary type="html">Inheritance of tokens after the owner&#x27;s death</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7878/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a standard interface for contracts to allow tokens to be inherited after the owner&#x27;s death. The interface allows token owners to set up a Will and designate executors to enable the transfer of tokens to inheritors after a specified waiting period.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Crypto Tokens in general and NFTs in particular are starting to be used to tokenise real-world assets. In order for them to be adopted by the main stream finance world, there needs to be a way to inherit these tokens after the owner has passed away. Currently, there is no standardised way for token holders to pass on their digital assets in the event of their death.&lt;br &#x2F;&gt;
This EIP aims to solve this problem by providing a standard interface for &quot;bequeathable&quot; tokens, allowing for a secure and transparent process of token inheritance.
In designing this interface we have tried to follow the real world process of Will creation and execution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Every compliant contract MUST implement the &lt;code&gt;Bequeathable&lt;&#x2F;code&gt; interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-7878 Bequeathable tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-7878&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Bequeathable interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Bequeathable&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Announce the owner&amp;#39;s tokens are to be inherited&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 Emitted by `announceObit`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;       The original owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   inheritor&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The address of the wallet that will inherit the tokens once the moratoriumTTL time has passed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ObituaryStarted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; inheritor&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               Announce the obituary (and moratorium) for the owner has been cancelled, as well as who cancelled it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  Emitted by `cancelObit`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The original owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   cancelledBy&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address that triggered this cancellation. This can be the owner or any of the inheritors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ObituaryCancelled&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; cancelledBy&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 A token owner can set a Will and names one or more executors who are able to transfer their tokens after their death&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                    Although more than one executor address can be set, only one is required to start the process and then do the transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                    Subsequent calls to this function should overwrite any existing Will&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   executors&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      An array of executors eg legal council, spouse, child 1, child 2 etc..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   moratoriumTTL&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The time that must pass (in seconds) from when the obituary is announced to when the inheritance transfer can take place&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                    The moratoriumTTL is a safety buffer time frame that allows for any intervention before the tokens get transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setWill&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; executors&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; moratoriumTTL&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  Get the details of a Will if set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                     This is a way for the owner to confirm that they have correctly set their Will&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;          The current owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   executors&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      A list of all the executors for this owners will&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   moratoriumTTL&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The length of time (in seconds) that must elapse after calling announceObit before the actual transfer can happen&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getWill&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; executors&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; moratoriumTTL&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Start the Obituary process, by announcing it and declaring who is the intended inheritor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;       The current owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   inheritor&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The address of the owner to be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; announceObit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; inheritor&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;          Cancel the Obituary that has been previously announced. Can be called by any of the executors (or the owner if still around)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The original owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cancelObit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   Get the designated inheritor and how much time is left before the moratoriumTTL is satisfied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           The current owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   inheritor&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;       The named inheritor when the obituary was announced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   moratoriumTTL&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The time left for the moratoriumTTL before the transfer can be done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                      A minus figure for moratoriumTTL indicates that the wait time has elapsed and the tokens can be bequeathed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getObit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; inheritor&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; moratoriumTTL&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Bequeath ie transfer the tokens to the previously declared inheritor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;   owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The original owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            The transfer should happen to the inheritor address when `announceObit` was called&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bequeath&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#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;h3 id=&quot;functions&quot;&gt;Functions&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;setWill&lt;&#x2F;code&gt;: Allows a token owner to set up or update their Will.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getWill&lt;&#x2F;code&gt;: Returns the current Will details for a given owner.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;announceObit&lt;&#x2F;code&gt;: Initiates the inheritance process by an executor.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cancelObit&lt;&#x2F;code&gt;: Cancels an active obituary process.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getObit&lt;&#x2F;code&gt;: Retrieves the current obituary status.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bequeath&lt;&#x2F;code&gt;: Transfers tokens to the inheritor after the waiting period.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ObituaryStarted&lt;&#x2F;code&gt;: Emitted when an obituary is announced.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ObituaryCancelled&lt;&#x2F;code&gt;: Emitted when an obituary is cancelled.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The standard follows what currently happens in real life when preparing and executing a Will.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;An owner writes a Will and in doing so names the executor(s) of their Will&lt;&#x2F;li&gt;
&lt;li&gt;Upon passing away, the executor will announce the Obituary&lt;&#x2F;li&gt;
&lt;li&gt;The Will is read and the inheritors are identified&lt;&#x2F;li&gt;
&lt;li&gt;The transfer of ownership is executed according to the wishes of the Will&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;However, real life is not always as straight forward as this. Conflicts happen all the time. To handle this situation and to keep the interface simple, we added the ability to cancel the Obituary by ANY of the executors. In this way, if there is any conflict, it can be challenged out in the courts and once the matter is settled, the Obituary process can start again.&lt;&#x2F;p&gt;
&lt;p&gt;Again to keep the interface clean, all the tokens get transferred to one address. It is then that person&#x27;s responsibility to execute any further transfers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is compatible with existing token standards like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;. It can be implemented alongside these standards without affecting their core functionality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7878&#x2F;.&#x2F;assets&#x2F;test&#x2F;Bequeath.test.js&quot;&gt;&lt;code&gt;Bequeath.test.js&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7878&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;Bequeathable.sol&quot;&gt;&lt;code&gt;Bequeathable.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Implementers should carefully consider access control mechanisms to ensure that only authorized parties can execute Will-related functions.&lt;&#x2F;p&gt;
&lt;p&gt;The moratoriumTTL should be set to a reasonable duration to allow for potential disputes or corrections. We recommend at least 30 days, especially for tokens that are of high value.  It limits the potential damage in scenarios such as the obituray process being triggered by a bad actor who has taken over one of the executor wallets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>AI Agents NFT with Private Metadata</title>
        <published>2025-01-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ming Wu</name><uri>https://github.com/sparkmiw</uri>
	</author>
	
	<author>
		<name>Jason Zeng</name><uri>https://github.com/zenghbo</uri>
	</author>
	
	<author>
		<name>Wei Wu</name><uri>https://github.com/Wilbert957</uri>
	</author>
	
	<author>
		<name>Michael Heinrich</name><uri>https://github.com/michaelomg</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7857/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7857-an-nft-standard-for-ai-agents-with-private-metadata/22391" />
        

        <id>https://wg-eips.ritovision.com/7857/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7857"
            label="ERC-7857" />
        

        
        

        
        <summary type="html">AI agent NFTs, enabling secure management of private metadata with verifiable data transfer</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7857/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for NFTs specifically designed for AI agents, where the metadata represents agent capabilities and requires privacy protection. Unlike traditional NFT standards that focus on static metadata, this standard introduces mechanisms for verifiable data ownership and secure transfer. By defining a unified interface for different verification methods (e.g., Trusted Execution Environment (TEE), Zero-Knowledge Proof (ZKP)), it enables secure management of valuable agent metadata such as models, memory, and character definitions, while maintaining confidentiality and verifiability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the increasing intelligence of AI models, agents have become powerful tools for automating meaningful daily tasks. The integration of agents with blockchain technology has been recognized as a major narrative in the crypto industry, with many projects enabling agent creation for their users. However, a crucial missing piece is the decentralized management of agent ownership.&lt;&#x2F;p&gt;
&lt;p&gt;AI agents possess inherent non-fungible properties that make them natural candidates for NFT representation:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each agent is unique, with its own model, memory, and character&lt;&#x2F;li&gt;
&lt;li&gt;Agents embody clear ownership rights, representing significant computational investment and intellectual property&lt;&#x2F;li&gt;
&lt;li&gt;Agents have private metadata (e.g., neural network models, memory, character definitions) that defines their capabilities&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;However, current NFT standards like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; are insufficient for representing AI agents as digital assets. While NFTs can establish ownership of digital items, using them to represent AI agents introduces unique challenges. The key issue lies in the metadata transfer mechanism. Unlike traditional NFTs where metadata is typically static and publicly accessible, an AI agent&#x27;s metadata (which constitutes the agent itself):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Has intrinsic value and is often the primary purpose of the transfer&lt;&#x2F;li&gt;
&lt;li&gt;Requires encrypted storage to protect intellectual property&lt;&#x2F;li&gt;
&lt;li&gt;Needs privacy-preserving and verifiable transfer mechanisms when ownership changes&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For example, when transferring an agent NFT, we need to ensure:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The actual transfer of encrypted metadata (the agent&#x27;s model, memory, character, etc.) is verifiable&lt;&#x2F;li&gt;
&lt;li&gt;The new owner can securely access the metadata that constitutes the agent&lt;&#x2F;li&gt;
&lt;li&gt;The agent&#x27;s execution environment can verify ownership and load appropriate metadata&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This EIP introduces a standard for NFTs with private metadata that addresses these requirements through privacy-preserving verification mechanisms, enabling secure ownership and transfer of valuable agent data while maintaining confidentiality and verifiability. This standard will serve as a foundation for the emerging agent ecosystem, allowing platforms to provide verifiable agent ownership and secure metadata management in a decentralized manner.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The EIP defines three key interfaces: the main NFT interface, the metadata interface, and the data verification interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-verification-system&quot;&gt;Data Verification System&lt;&#x2F;h3&gt;
&lt;p&gt;The verification system consists of two core components that work together to ensure secure data operations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;On-chain Verifier (data verification interface)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Implemented as a smart contract&lt;&#x2F;li&gt;
&lt;li&gt;Verifies proofs submitted through contract calls&lt;&#x2F;li&gt;
&lt;li&gt;Returns structured verification results&lt;&#x2F;li&gt;
&lt;li&gt;Can be implemented using different verification mechanisms (TEE&#x2F;ZKP)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Off-chain Prover&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generates proofs for ownership and availability claims&lt;&#x2F;li&gt;
&lt;li&gt;Works with encrypted data and keys&lt;&#x2F;li&gt;
&lt;li&gt;Implementation varies based on verification mechanism:
&lt;ul&gt;
&lt;li&gt;TEE-based: Generates proofs within trusted hardware&lt;&#x2F;li&gt;
&lt;li&gt;ZKP-based: Creates cryptographic zero-knowledge proofs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The system supports two types of proofs:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ownership Proof&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generated by Prover with access to original data&lt;&#x2F;li&gt;
&lt;li&gt;Proves knowledge of pre-images for claimed dataHashes&lt;&#x2F;li&gt;
&lt;li&gt;Verified on-chain through &lt;code&gt;verifyOwnership()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transfer Validity Proof&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generated by Prover for data transfers&lt;&#x2F;li&gt;
&lt;li&gt;Proves:
&lt;ul&gt;
&lt;li&gt;Knowledge of original data (pre-images)&lt;&#x2F;li&gt;
&lt;li&gt;Correct decryption and re-encryption of data&lt;&#x2F;li&gt;
&lt;li&gt;Secure key transmission (using receiver&#x27;s public key to encrypt the new key)&lt;&#x2F;li&gt;
&lt;li&gt;Data availability in storage (using receiver&#x27;s signature to confirm the data is available in storage)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Verified on-chain through &lt;code&gt;verifyTransferValidity()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The ownership verification is optional because when the minted token is transferred or cloned, the ownership verification is checked again inside the availability verification. It&#x27;s better to be safe than sorry, so we recommend doing ownership verification for minting and updates.&lt;&#x2F;p&gt;
&lt;p&gt;Different verification mechanisms have distinct capabilities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TEE-based Implementation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Prover runs in trusted hardware&lt;&#x2F;li&gt;
&lt;li&gt;Can handle private keys securely&lt;&#x2F;li&gt;
&lt;li&gt;Enables direct data re-encryption&lt;&#x2F;li&gt;
&lt;li&gt;Verifier checks TEE attestations&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ZKP-based Implementation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Prover generates cryptographic proofs&lt;&#x2F;li&gt;
&lt;li&gt;Cannot handle multi-party private keys&lt;&#x2F;li&gt;
&lt;li&gt;Re-encryption key known to prover&lt;&#x2F;li&gt;
&lt;li&gt;Requires additional re-encryption when next update, otherwise the new update is still visible to the prover&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;data-verification-interface&quot;&gt;Data Verification Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The type of the oracle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; There are two types of oracles: TEE and ZKP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OracleType&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;    TEE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;    ZKP&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The access proof which is a signature signed by the receiver (the receiver may delegate the signing privilege to the access assistant)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; oldDataHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the old data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newDataHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the new data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The nonce of the access proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; encryptedPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The encrypted public key, the receiver&amp;#39;s public key which used to encrypt the new data key. `encryptedPubKey` can be empty in `accessProof`, and means that use the receiver&amp;#39;s ethereum public key to encrypt the new data key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccessProof&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; newDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ownership proof which is a signature signed by the receiver (the receiver may delegate the signing privilege to the access assistant)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; proofType&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The type of the proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; oldDataHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the old data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newDataHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the new data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sealedKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The sealed key of the new data key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; encryptedPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The encrypted public key, the receiver&amp;#39;s public key which used to encrypt the new data key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The nonce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OwnershipProof&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    OracleType oracleType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The type of the oracle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the old data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; newDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash of the new data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; sealedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The sealed key of the new data key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The encrypted public key, the receiver&amp;#39;s public key which used to encrypt the new data key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The nonce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The proof&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 class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    AccessProof accessProof&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    OwnershipProof ownershipProof&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; newDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; sealedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; wantedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; accessAssistant&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; accessProofNonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&gt; ownershipProofNonce&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify data transfer validity, the _proofs prove:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         1. The pre-image of oldDataHashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         2. The oldKey (old data key) can decrypt the pre-image and the new key re-encrypt the plaintexts to new ciphertexts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         3. The newKey (new data key) is encrypted using the encryptedPubKey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         4. The hashes of new ciphertexts is newDataHashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         5. The newDataHashes identified ciphertexts are available in the storage: need the signature from the receiver or the access assistant signing oldDataHashes, newDataHashes, and encryptedPubKey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _proofs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Proof generated by TEE&#x2F;ZKP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyTransferValidity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _proofs&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;metadata-interface&quot;&gt;Metadata Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IntelligentData&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; dataDescription&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; dataHash&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857Metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the name of the NFT collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the symbol of the NFT collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the data hash of a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; current data hash of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; intelligentDataOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;main-nft-interface&quot;&gt;Main NFT Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an address is approved to transfer a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is approving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is being approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an address is approved for all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an address is authorized to use a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is authorizing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is being authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Authorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an address is revoked from using a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is revoking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is being revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AuthorizationRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when a token is transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is transferring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is receiving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when a token is cloned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is cloning&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is receiving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Cloned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when a sealed key is published&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that is receiving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _sealedKeys&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The sealed keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublishedSealedKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _sealedKeys&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when a user is delegated to an assistant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _assistant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The assistant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DelegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _assistant&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The verifier interface that this NFT uses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the verifier contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer data with ownership&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to transfer data to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to transfer data for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _proofs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Proofs of data available for _to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _proofs&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Clone data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to clone data to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to clone data for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _proofs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Proofs of data available for _to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the newly cloned token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iClone&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _proofs&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newTokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add authorized user to group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to add to group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeUsage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revoke authorization from a user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to revoke authorization from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user to revoke authorization from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeAuthorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approve an address to transfer a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Set approval for all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Delegate access check to an assistant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _assistant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The assistant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _assistant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get token owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; current owner of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the authorized users of a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; current authorized users of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizedUsersOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the approved address for a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; approved address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if an address is approved for all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the delegate access for a user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; delegate access&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getDelegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The design choices in this standard are motivated by several key requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verification Abstraction&lt;&#x2F;strong&gt;: The standard separates the verification logic into a dedicated interface (&lt;code&gt;IDataVerifier&lt;&#x2F;code&gt;), allowing different verification mechanisms (TEE, ZKP) to be implemented and used interchangeably. The verifier should support two types of proof:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ownership Proof Verifies that the prover possesses the original data by demonstrating knowledge of the pre-images that generate the claimed dataHashes&lt;&#x2F;li&gt;
&lt;li&gt;Transfer Validity Proof Verifies secure data integrity and availability by proving: knowledge of the original data (pre-images of oldDataHashes); ability to decrypt with oldKey and re-encrypt with newKey; secure transmission of newKey using recipient&#x27;s public key; integrity of the newly encrypted data matching newDataHashes; and data availability confirmed by recipient&#x27;s signature on both &lt;code&gt;oldDataHashes&lt;&#x2F;code&gt; and &lt;code&gt;newDataHashes&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Protection&lt;&#x2F;strong&gt;: The standard uses data hashes and encrypted keys to ensure that valuable NFT data remains protected while still being integrity and availability verifiable&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flexible Data Management&lt;&#x2F;strong&gt;: Three distinct data operations are supported:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Full transfer, where the data and ownership are transferred to the new owner&lt;&#x2F;li&gt;
&lt;li&gt;Data cloning, where the data is cloned to a new token but the ownership is not transferred&lt;&#x2F;li&gt;
&lt;li&gt;Data usage authorization, where the data is authorized to be used by a specific user, but the ownership is not transferred, and the user still cannot access the data. This need an environment to authenticate the user and process the request from the authorized user secretly, we call it &quot;Sealed Executor&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sealed Executor&lt;&#x2F;strong&gt;: Although the Sealed Executor is not defined and out of the scope of this standard, it is a crucial component for the standard to work. The Sealed Executor is an environment that can authenticate the user and process the request from the authorized user secretly. The Sealed Executor should get authorized group by tokenId, and the verify the signature of the user using the public keys in the authorized group. If the verification is successful, the executor will process the request and return the result to the user, and the sealed executor could be implemented by a trusted party (where permitted), TEE or Fully Homomorphic Encryption (FHE)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not inherit from existing NFT standards to maintain its focus on functional data management. However, implementations can choose to additionally implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; if traditional NFT compatibility is desired.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;verifier&quot;&gt;Verifier&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;abstract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BaseVerifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; prevent replay attack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; usedProofs&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; prevent replay attack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; proofTimestamps&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _checkAndMarkProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofNonce&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;usedProofs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;proofNonce&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Proof already used&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        usedProofs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;proofNonce&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        proofTimestamps&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;proofNonce&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; clean expired proof records (save gas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cleanExpiredProofs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofNonces&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; proofNonces&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            bytes32&lt;&#x2F;span&gt;&lt;span&gt; nonce &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proofNonces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;usedProofs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;                block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; proofTimestamps&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                delete&lt;&#x2F;span&gt;&lt;span&gt; usedProofs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                delete&lt;&#x2F;span&gt;&lt;span&gt; proofTimestamps&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; __gap&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AttestationConfig&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    OracleType oracleType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; contractAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Verifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    BaseVerifier&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    Initializable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    AccessControlUpgradeable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    PausableUpgradeable&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 class=&quot;z-keyword&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ECDSA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MessageHashUtils&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bytes32&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AttestationContractUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;AttestationConfig&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; attestationConfigs&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ADMIN_ROLE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ADMIN_ROLE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; PAUSER_ROLE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;PAUSER_ROLE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;OracleType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; attestationContract&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; maxProofAge&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; VERSION &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;2.0.0&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @custom:oz&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-upgrades-unsafe-allow constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _disableInitializers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initialize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        AttestationConfig&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _admin&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initializer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        __AccessControl_init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        __Pausable_init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            attestationContract&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oracleType&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 class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contractAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        maxProofAge &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; days&lt;&#x2F;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;DEFAULT_ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;PAUSER_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _admin&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AttestationContractUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_attestationConfigs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateAttestationContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        AttestationConfig&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _attestationConfigs&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            attestationContract&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oracleType&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 class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _attestationConfigs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contractAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AttestationContractUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_attestationConfigs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateMaxProofAge&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _maxProofAge&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&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&gt;        maxProofAge &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _maxProofAge&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;PAUSER_ROLE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _pause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unpause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;PAUSER_ROLE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _unpause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; teeOracleVerify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; messageHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            TEEVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;attestationContract&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;OracleType&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;TEE&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;verifyTEESignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                messageHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                signature&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Extract and verify signature from the access proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; accessProof&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The access proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; recovered access assistant address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyAccessibility&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        AccessProof&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accessProof&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 class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; messageHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-string&quot;&gt;                &amp;quot;\x19Ethereum Signed Message:\n66&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&gt;                Strings&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toHexString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;                            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;                                accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;                    32&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; accessAssistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; messageHash&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;recover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proof&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;accessAssistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid access assistant&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; accessAssistant&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verfifyOwnershipProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        OwnershipProof&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ownershipProof&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 class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oracleType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; OracleType&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;TEE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            bytes32&lt;&#x2F;span&gt;&lt;span&gt; messageHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;                abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-string&quot;&gt;                    &amp;quot;\x19Ethereum Signed Message:\n66&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&gt;                    Strings&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toHexString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;                                abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;                                    ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sealedKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;                        32&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; teeOracleVerify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;messageHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;proof&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: add ZKP verification&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Process a single transfer validity proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The proof data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The processed proof data as a struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; processTransferProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proof&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 class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; output&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; compare the proof data in access proof and ownership proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;Invalid oldDataHashes&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;Invalid newDataHashes&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash&lt;&#x2F;span&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&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;wantedKey &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProofNonce &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sealedKey &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sealedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProofNonce &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; verify the access assistant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyAccessibility&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProof&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; isOwn &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verfifyOwnershipProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProof&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;isOwn&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid ownership proof&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify data transfer validity, the _proof prove:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         1. The pre-image of oldDataHashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         2. The oldKey can decrypt the pre-image and the new key re-encrypt the plaintexts to new ciphertexts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         3. The newKey is encrypted with the receiver&amp;#39;s pubKey to get the sealedKey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         4. The hashes of new ciphertexts is newDataHashes (key to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: TEE could support a private key of the receiver)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         5. The newDataHashes identified ciphertexts are available in the storage: need the signature from the receiver signing oldDataHashes and newDataHashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; proofs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Proof generated by TEE&#x2F;ZKP oracle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyTransferValidity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt;        public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        virtual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        override&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        whenNotPaused&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;            memory&lt;&#x2F;span&gt;&lt;span&gt; outputs &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span&gt; TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proofs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            TransferValidityProofOutput &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;memory&lt;&#x2F;span&gt;&lt;span&gt; output &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; processTransferProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                proofs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&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;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&gt;            outputs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;            bytes32&lt;&#x2F;span&gt;&lt;span&gt; accessProofNonce &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessProofNonce&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            _checkAndMarkProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;accessProofNonce&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            bytes32&lt;&#x2F;span&gt;&lt;span&gt; ownershipProofNonce &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ownershipProofNonce&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            _checkAndMarkProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ownershipProofNonce&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; outputs&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; __gap&lt;&#x2F;span&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;h3 id=&quot;main-nft&quot;&gt;Main NFT&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AgentNFT&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    AccessControlEnumerableUpgradeable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    IERC7857&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    IERC7857Metadata&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Updated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-variable&quot;&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _oldDatas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newDatas&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&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Minted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _creator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&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;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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenData&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; approvedUser&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; iDatas&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @custom:storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-location erc7201:agent.storage.AgentNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AgentNFTStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; TokenData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; tokens&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; operatorApprovals&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; user &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; accessAssistant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; accessAssistants&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; nextTokenId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Contract metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; storageInfo&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Core components&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC7857DataVerifier verifier&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ADMIN_ROLE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ADMIN_ROLE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; PAUSER_ROLE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;PAUSER_ROLE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; VERSION &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;2.0.0&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256(abi.encode(uint(keccak256(&amp;quot;agent.storage.AgentNFT&amp;quot;)) - 1)) &amp;amp; ~bytes32(uint(0xff))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; AGENT_NFT_STORAGE_LOCATION &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        0x4aa80aaafbe0e5fe3fe1aa97f3c1f8c65d61f96ef1aab2b448154f4e07594600&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        private&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        pure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AgentNFTStorage&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; AGENT_NFT_STORAGE_LOCATION&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @custom:oz&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-upgrades-unsafe-allow constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _disableInitializers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initialize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; storageInfo_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verifierAddr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; admin_&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initializer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;verifierAddr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        __AccessControlEnumerable_init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;DEFAULT_ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; admin_&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; admin_&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;PAUSER_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; admin_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;name &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;symbol &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; symbol_&lt;&#x2F;span&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;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;storageInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; storageInfo_&lt;&#x2F;span&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;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;verifier &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;verifierAddr&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Basic getters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;symbol&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;verifier&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Admin functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newVerifier&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newVerifier &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;verifier &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7857DataVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newVerifier&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newDatas&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        TokenData &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Empty data array&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; oldDatas &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span&gt; IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;            token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            oldDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        delete&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; newDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Updated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; oldDatas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newDatas&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; iDatas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Empty data array&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokenId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nextTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;        TokenData &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; newToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Minted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _proofCheck&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt;        internal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sealedKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newDatas&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proofs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Empty proofs array&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        TransferValidityProofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; proofOutput &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            .&lt;&#x2F;span&gt;&lt;span&gt;verifier&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 class=&quot;z-entity z-name&quot;&gt;verifyTransferValidity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proofs&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            proofOutput&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Proof count mismatch&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&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&gt;        sealedKeys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;proofOutput&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&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&gt;        newDatas &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span&gt; IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proofOutput&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; proofOutput&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; require the initial data hash is the same as the old data hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;oldDataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&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;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;Old data hash mismatch&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&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only the receiver itself or the access assistant can sign the access proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistants&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                &amp;quot;Access assistant mismatch&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&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 class=&quot;z-support&quot;&gt;            bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; wantedKey &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;wantedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; encryptedPubKey &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;wantedKey&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if the wanted key is empty, the default wanted receiver is receiver itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                address&lt;&#x2F;span&gt;&lt;span&gt; defaultWantedReceiver &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pubKeyToAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    encryptedPubKey&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                    defaultWantedReceiver &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                    &amp;quot;Default wanted receiver mismatch&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&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;span class=&quot;z-keyword&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 class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if the wanted key is not empty, the data is private&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                    Utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;bytesEqual&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;encryptedPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; wantedKey&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                    &amp;quot;encryptedPubKey mismatch&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sealedKeys&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sealedKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            newDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IntelligentData&lt;&#x2F;span&gt;&lt;span&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&gt;                dataDescription&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataDescription&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                dataHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; proofOutput&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;newDataHash&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&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;sealedKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newDatas&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; sealedKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; newDatas&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 class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _proofCheck&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        TokenData &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        delete&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; newDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublishedSealedKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sealedKeys&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        TokenData &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _clone&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-support&quot;&gt;            bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; sealedKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; newDatas&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 class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _proofCheck&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; newTokenId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nextTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;        TokenData &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; newToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;newTokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; newDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            newToken&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newDatas&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Cloned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublishedSealedKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sealedKeys&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; newTokenId&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iClone&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _clone&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iCloneFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        TransferValidityProof&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proofs&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _clone&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proofs&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeUsage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Already authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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&gt;        authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Authorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizedUsersOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; storageInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;storageInfo&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; intelligentDataOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IntelligentData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iDatas&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Approval to current owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-variable z-language&quot;&gt;            msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;operator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Approve to caller&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operatorApprovals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;operator&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approvedUser&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operatorApprovals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;operator&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assistant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;assistant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistants&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; assistant&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DelegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; assistant&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getDelegateAccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;accessAssistants&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;spender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            getApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; spender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchAuthorizeUsage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; users&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;users&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Empty users array&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; users&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address in users&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Authorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeAuthorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        AgentNFTStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAgentStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;user &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; found &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&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&gt;                authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                authorizedUsers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pop&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;                found &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;                break&lt;&#x2F;span&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;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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;found&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;User not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AuthorizationRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Proof Verification&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Implementations must carefully verify all assertions in the proof&lt;&#x2F;li&gt;
&lt;li&gt;Replay attacks must be prevented&lt;&#x2F;li&gt;
&lt;li&gt;Different verification systems have their own security considerations, and distinct capabilities regarding key management: TEE can securely handle private keys from multi-parties, enabling direct data re-encryption. However, ZKP, due to its cryptographic nature, cannot process private keys from multi-parties. As a result, the re-encryption key is also from the prover (i.e., the sender), so tokens acquired through transfer or cloning must undergo re-encryption during their next update, otherwise the new update is still visible to the previous owner. This distinction in key handling capabilities affects how data transformations are managed during later usage&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Data Privacy&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Only hashes and sealed keys are stored on-chain, actual functional data must be stored and transmitted securely off-chain&lt;&#x2F;li&gt;
&lt;li&gt;Key management is crucial for secure data access&lt;&#x2F;li&gt;
&lt;li&gt;TEE verification system could support private key of the receiver, but ZKP verification system could not. So when using ZKP, the token transferred or cloned from other should be re-encrypted when next update, otherwise the new update is still visible to the previous owner&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Access Control and State Management&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Operations restricted to token owners only&lt;&#x2F;li&gt;
&lt;li&gt;All data operations must maintain integrity and availability&lt;&#x2F;li&gt;
&lt;li&gt;Critical state changes (sealed keys, ownership, permissions) must be atomic and verifiable&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Sealed Executor&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Although out of scope for this standard, the Sealed Executor is crucial for secure operation&lt;&#x2F;li&gt;
&lt;li&gt;The Sealed Executor authenticates users and processes requests in a secure environment by verifying user signatures against authorized public keys for each tokenId&lt;&#x2F;li&gt;
&lt;li&gt;The Sealed Executor can be implemented through a trusted party (where permitted), TEE or FHE&lt;&#x2F;li&gt;
&lt;li&gt;Ensuring secure request processing and result delivery&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Add blob schedule to EL config files</title>
        <published>2024-12-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7840/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/add-blob-schedule-to-execution-client-configuration-files/22182" />
        

        <id>https://wg-eips.ritovision.com/7840/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7840"
            label="EIP-7840" />
        

        
        

        
        <summary type="html">Include a per-fork blob parameters in client configuration files</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7840/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add a new object to client configuration files &lt;code&gt;blobSchedule&lt;&#x2F;code&gt; which lists the
target blob count per block and max blob count per block for each fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;ensure there is a way to dynamically adjust the target and max blob counts per
block&lt;&#x2F;li&gt;
&lt;li&gt;ensure there is a way to dynamically adjust the blob base fee update fraction&lt;&#x2F;li&gt;
&lt;li&gt;avoid complex handshake over engine API&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Extend client configuration files with the object &lt;code&gt;blobSchedule&lt;&#x2F;code&gt;, which has the
following shape:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;blobSchedule&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;cancun&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3338477&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prague&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;baseFeeUpdateFraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5007716&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;Clients must configure the target, max and baseFeeUpdateFraction per-fork. The behavior
when the configuration is missing or incomplete for a fork is undefined. Clients
are free to choose how to handle this situation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Although maintaining the target and max blob only in the consensus client is
desirable, we acknowledge the reality that execution clients need these values
for various activities. For example, the &lt;code&gt;eth_feeHistory&lt;&#x2F;code&gt; RPC method returns a
field &lt;code&gt;blobGasUsedRatio&lt;&#x2F;code&gt; that does require the max, even though the core
protocol doesn&#x27;t specifically need such value. Passing this value over the
engine API every block seem overkill so we believe a configuration value is a
good middle ground. Additionally, the &lt;code&gt;baseFeeUpdateFraction&lt;&#x2F;code&gt; parameter was added to adjust the responsiveness of blob gas pricing per fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security considerations found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Diffusive Tokens</title>
        <published>2024-12-07T00:00:00+00:00</published>
        <updated>2026-04-25T12:06:20+00:00</updated>
	
	
	<author>
		<name>Cheng Qian</name><uri>https://github.com/jamesavechives</uri><email>james.walstonn@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7837/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7837-diffusive-tokens/21989" />
        

        <id>https://wg-eips.ritovision.com/7837/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7837"
            label="ERC-7837" />
        

        
        

        
        <summary type="html">A fungible token that mints new tokens on transfer, charges a per-token native fee, and enforces a capped supply.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7837/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC proposes a standard for a new type of fungible token, called &lt;strong&gt;Diffusive Tokens (DIFF)&lt;&#x2F;strong&gt;. Unlike traditional &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens, transferring DIFF tokens does not decrease the sender’s balance. Instead, it &lt;em&gt;mints&lt;&#x2F;em&gt; new tokens directly to the recipient, increasing the total supply on every transfer action. A fixed native currency fee is charged per token transferred, and this fee is paid by the sender to the contract owner. The supply growth is limited by a maximum supply set by the owner. Token holders can also burn their tokens to reduce the total supply. These features enable a controlled, incentivized token distribution model that merges fungibility with a built-in economic mechanism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Traditional &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens maintain a constant total supply and simply redistribute balances on transfers. While this model is widespread, certain use cases benefit from a token design that continuously expands supply during transfers, simulating a controlled &quot;diffusion&quot; of value. The Diffusive Token model may be suitable for representing claims on real-world goods (e.g., a product batch like iPhone 15 units), digital goods, or controlled asset distributions where initial token distribution and ongoing availability need to be managed differently.&lt;&#x2F;p&gt;
&lt;p&gt;This model also includes a native currency fee per token transferred, incentivizing careful, value-driven transfers and providing a revenue stream for the token’s issuer. The maximum supply cap prevents unbounded inflation, ensuring long-term scarcity. The ability for owners to burn tokens to redeem underlying goods or services directly maps on-chain assets to real-world redemptions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Use Cases&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Real-World Asset Backing&lt;&#x2F;strong&gt;: A manufacturer can issue DIFF tokens representing a batch of products (e.g., iPhones). Each token can be redeemed (burned) for one physical item.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fee-Driven Incentives&lt;&#x2F;strong&gt;: The transfer fee ensures that infinite minting by constant transferring is economically disincentivized. The fee also supports the token issuer or provides a funding mechanism.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;terminology&quot;&gt;Terminology&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Diffusive Token&lt;&#x2F;strong&gt;: A fungible token unit that is minted on transfers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Max Supply&lt;&#x2F;strong&gt;: The maximum total supply the token can reach.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transfer Fee&lt;&#x2F;strong&gt;: A fee in native blockchain currency (e.g., ETH) that must be paid by the sender for each token transferred. The total fee = &lt;code&gt;transferFee * amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Burn&lt;&#x2F;strong&gt;: The action of destroying tokens, reducing both the holder’s balance and the total supply.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;data-structures&quot;&gt;Data Structures&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Total Supply and Max Supply&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; maxSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transfer Fee&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; transferFee&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; fee per token transferred in wei&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner&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;owner&lt;&#x2F;code&gt; sets and updates &lt;code&gt;transferFee&lt;&#x2F;code&gt; and &lt;code&gt;maxSupply&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;token-semantics&quot;&gt;Token Semantics&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minting on Transfer&lt;&#x2F;strong&gt;
When a transfer occurs from &lt;code&gt;A&lt;&#x2F;code&gt; to &lt;code&gt;B&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A&lt;&#x2F;code&gt; does not lose any tokens.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;B&lt;&#x2F;code&gt; receives newly minted tokens (increasing their balance and totalSupply).&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;totalSupply&lt;&#x2F;code&gt; increases by the transferred amount, but must not exceed &lt;code&gt;maxSupply&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fixed Transfer Fee in Native Currency&lt;&#x2F;strong&gt;
Each transfer requires the sender to pay &lt;code&gt;transferFee * amount&lt;&#x2F;code&gt; in the native currency. If &lt;code&gt;msg.value&lt;&#x2F;code&gt; is insufficient, the transaction reverts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maximum Supply&lt;&#x2F;strong&gt;
If a transfer would cause &lt;code&gt;totalSupply + amount &amp;gt; maxSupply&lt;&#x2F;code&gt;, it must revert.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Burning Tokens&lt;&#x2F;strong&gt;
Token holders can burn tokens to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce their balance by the burned amount.&lt;&#x2F;li&gt;
&lt;li&gt;Decrease &lt;code&gt;totalSupply&lt;&#x2F;code&gt; by the burned amount.
This can map to redeeming underlying goods or simply deflating the token.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The DIFF standard aligns partially with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, but redefines certain behaviors:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Core Functions:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function balanceOf(address account) external view returns (uint256);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function transfer(address to, uint256 amount) external payable returns (bool);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Modified behavior&lt;&#x2F;strong&gt;: Mints &lt;code&gt;amount&lt;&#x2F;code&gt; tokens to &lt;code&gt;to&lt;&#x2F;code&gt;, requires &lt;code&gt;msg.value &amp;gt;= transferFee * amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function burn(uint256 amount) external;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reduces sender’s balance and &lt;code&gt;totalSupply&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Administration Functions (Owner Only):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function setMaxSupply(uint256 newMax) external;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function setTransferFee(uint256 newFee) external;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function withdrawFees(address payable recipient) external;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Withdraws accumulated native currency fees.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Optional Approval Interface (For Compatibility):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function approve(address spender, uint256 amount) external returns (bool);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function transferFrom(address from, address to, uint256 amount) external payable returns (bool);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Modified behavior&lt;&#x2F;strong&gt;: Similar to &lt;code&gt;transfer&lt;&#x2F;code&gt;, but uses allowance and still mints tokens to &lt;code&gt;to&lt;&#x2F;code&gt; rather than redistributing from &lt;code&gt;from&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event Transfer(address indexed from, address indexed to, uint256 amount);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Emitted when tokens are minted to &lt;code&gt;to&lt;&#x2F;code&gt; via a transfer call.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event Burn(address indexed burner, uint256 amount);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Emitted when &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens are burned from an address.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event FeeUpdated(uint256 newFee);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Emitted when the owner updates the &lt;code&gt;transferFee&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event MaxSupplyUpdated(uint256 newMaxSupply);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Emitted when the owner updates &lt;code&gt;maxSupply&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;compliance-with-erc-20&quot;&gt;Compliance with ERC-20&lt;&#x2F;h3&gt;
&lt;p&gt;The DIFF standard implements the ERC-20 interface but significantly alters the &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; semantics:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fungibility&lt;&#x2F;strong&gt;: Each token unit is identical and divisible as in ERC-20.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Balances and Transfers&lt;&#x2F;strong&gt;: The &lt;code&gt;balanceOf&lt;&#x2F;code&gt; function works as normal. However, &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; no longer redistribute tokens. Instead, they mint new tokens (up to &lt;code&gt;maxSupply&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Approvals&lt;&#x2F;strong&gt;: The &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; functions remain, but their logic is unconventional since the sender’s balance is never reduced by transfers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While the DIFF standard can be seen as ERC-20 compatible at the interface level, the underlying economics differ substantially.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Design Decisions&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unlimited Minting vs. Max Supply&lt;&#x2F;strong&gt;: Allowing minting on every transfer provides a “diffusive” spread of tokens. The &lt;code&gt;maxSupply&lt;&#x2F;code&gt; prevents uncontrolled inflation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Burn Mechanism&lt;&#x2F;strong&gt;: Enables redemption or deflation as tokens are taken out of circulation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Owner Controls&lt;&#x2F;strong&gt;: The owner (e.g., issuer) can adjust fees and max supply, maintaining flexibility as market conditions change.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The DIFF standard is interface-compatible with ERC-20 but not behaviorally identical. Any system integrating DIFF tokens should understand the difference in minting on transfer.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wallets and Exchanges&lt;&#x2F;strong&gt;: Most ERC-20 compatible tools can display balances and initiate transfers. However, the unusual economics (mint on transfer) may confuse users and pricing mechanisms.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Allowances and TransferFrom&lt;&#x2F;strong&gt;: Still implemented for interoperability, but the expected logic (debiting &lt;code&gt;from&lt;&#x2F;code&gt; balance) does not apply.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initial Conditions&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Deploy contract with &lt;code&gt;maxSupply = 1,000,000 DIFF&lt;&#x2F;code&gt;, &lt;code&gt;transferFee = 0.001 ETH&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;totalSupply = 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Owner sets parameters and verifies via &lt;code&gt;maxSupply()&lt;&#x2F;code&gt; and &lt;code&gt;transferFee()&lt;&#x2F;code&gt; getters.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minting on Transfer&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;User A calls &lt;code&gt;transfer(B, 100)&lt;&#x2F;code&gt; with &lt;code&gt;msg.value = 0.1 ETH&lt;&#x2F;code&gt; (assuming &lt;code&gt;transferFee = 0.001 ETH&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Check &lt;code&gt;balances[B] == 100&lt;&#x2F;code&gt;, &lt;code&gt;totalSupply == 100&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Check that the contract now holds 0.1 ETH from the fee.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exceeding Max Supply&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;totalSupply = 999,950&lt;&#x2F;code&gt; and someone tries to transfer 100 tokens, causing &lt;code&gt;totalSupply&lt;&#x2F;code&gt; to exceed &lt;code&gt;1,000,000&lt;&#x2F;code&gt;, the transaction reverts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Burning Tokens&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;User B calls &lt;code&gt;burn(50)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Check &lt;code&gt;balances[B] == 50&lt;&#x2F;code&gt;, &lt;code&gt;totalSupply == 50&lt;&#x2F;code&gt; less than before.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Burn&lt;&#x2F;code&gt; event emitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Updating Fee and Withdrawing Funds&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Owner calls &lt;code&gt;setTransferFee(0.002 ETH)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FeeUpdated&lt;&#x2F;code&gt; event emitted.&lt;&#x2F;li&gt;
&lt;li&gt;Owner calls &lt;code&gt;withdrawFees(ownerAddress)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Check that &lt;code&gt;ownerAddress&lt;&#x2F;code&gt; receives accumulated fees.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation is provided under the asset folder in the EIPs repository. The implementation includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A basic contract implementing the DIFF standard.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DiffusiveToken&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; State Variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; decimals&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; maxSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; transferFee&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fee per token transferred in wei&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; burner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FeeUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newFee&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MaxSupplyUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newMaxSupply&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Modifiers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: caller is not the owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Constructor sets the initial parameters for the Diffusive Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token symbol&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _decimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Decimal places&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _maxSupply&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The max supply of tokens that can ever exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _transferFee&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initial fee per token transferred in wei&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _decimals&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _maxSupply&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transferFee&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&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        name &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        symbol &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        decimals &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _decimals&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        maxSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _maxSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        transferFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _transferFee&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&gt;        totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initially, no tokens are minted&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; External and Public Functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the token balance of the given address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers `amount` tokens to address `to`, minting new tokens in the process.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requires payment of native currency: transferFee * amount.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Recipient address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if successful&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: transfer to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: amount must be greater than zero&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; requiredFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; transferFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; requiredFee&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: insufficient fee&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check max supply limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; maxSupply&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: would exceed max supply&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mint new tokens to `to`&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;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Burns `amount` tokens from the caller&amp;#39;s balance, decreasing total supply.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of tokens to burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: burn amount must be greater than zero&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approves `spender` to transfer up to `amount` tokens on behalf of `msg.sender`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address authorized to spend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The max amount they can spend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;spender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: approve to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        allowances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;spender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current allowance of `spender` for `owner`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address allowed to spend the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; allowances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_owner&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_spender&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers `amount` tokens from `from` to `to` using the allowance mechanism.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `from` account does not lose tokens; this still mints to `to`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address from which the allowance has been given&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of tokens to transfer (mint)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: transfer to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: amount must be greater than zero&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; allowed &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; allowances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;allowed &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: allowance exceeded&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deduct from allowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        allowances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; allowed &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; requiredFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; transferFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; requiredFee&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: insufficient fee&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check max supply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; maxSupply&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: would exceed max supply&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mint tokens to `to`&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;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        totalSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner Functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Updates the maximum supply of tokens. Must be &amp;gt;= current totalSupply.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newMaxSupply&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new maximum supply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setMaxSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newMaxSupply&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newMaxSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: new max &amp;lt; current supply&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        maxSupply &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newMaxSupply&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MaxSupplyUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newMaxSupply&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Updates the per-token transfer fee.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newFee&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new fee in wei per token transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTransferFee&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newFee&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;        transferFee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newFee&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FeeUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newFee&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allows the owner to withdraw accumulated native currency fees.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that will receive the withdrawn fees&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; withdrawFees&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;recipient &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: withdraw to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; balance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&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;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;DiffusiveToken: withdrawal failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fallback and Receive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allows the contract to receive Ether.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Interfaces and helper contracts for testing and demonstration purposes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reentrancy&lt;&#x2F;strong&gt;: Handle fee transfers using the Checks-Effects-Interactions pattern. Consider &lt;code&gt;ReentrancyGuard&lt;&#x2F;code&gt; from OpenZeppelin to prevent reentrant calls.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Overflow&#x2F;Underflow&lt;&#x2F;strong&gt;: Solidity 0.8.x guards against this by default.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Contract Balance Management&lt;&#x2F;strong&gt;: Ensure enough native currency is sent to cover fees. Revert on insufficient fees.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Access Control&lt;&#x2F;strong&gt;: Only the owner can update &lt;code&gt;transferFee&lt;&#x2F;code&gt; and &lt;code&gt;maxSupply&lt;&#x2F;code&gt;. Use proper &lt;code&gt;onlyOwner&lt;&#x2F;code&gt; modifiers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Transaction Gas Limit Cap</title>
        <published>2024-11-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Giulio Rebuffo</name><uri>https://github.com/Giulio2002</uri>
	</author>
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7825/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7825-transaction-gas-limit-cap/21848" />
        

        <id>https://wg-eips.ritovision.com/7825/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7825"
            label="EIP-7825" />
        

        
        

        
        <summary type="html">Introduce a protocol-level cap on the maximum gas used by a transaction to 16,777,216 (2^24).</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7825/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces a protocol-level cap on the maximum gas usage per transaction to 16,777,216 (2^24) gas. By implementing this limit, Ethereum can enhance its resilience against certain DoS vectors, improve network stability, and provide more predictability to transaction processing costs, especially in the context of increasing the gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, transactions can theoretically consume up to the entire block gas limit, which poses several risks:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DoS Attacks&lt;&#x2F;strong&gt;: A single transaction consuming most or all of the block gas can result in uneven load distribution and impact network stability.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;State Bloat Risks&lt;&#x2F;strong&gt;: High-gas transactions often result in larger state changes, increasing the burden on nodes and exacerbating the Ethereum state growth problem.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Validation Overhead&lt;&#x2F;strong&gt;: High-gas transactions can lead to longer block verification times, negatively impacting user experience and network decentralization.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;By limiting individual transactions to a maximum of 16,777,216 gas, we aim to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce the risks of single-transaction DoS attacks.&lt;&#x2F;li&gt;
&lt;li&gt;Promote fairer gas allocation across transactions within a block.&lt;&#x2F;li&gt;
&lt;li&gt;Ensure better synchronization among nodes by mitigating extreme block validation times.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gas-cap&quot;&gt;Gas Cap&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Enforce a protocol-level maximum of &lt;strong&gt;16,777,216 gas (2^24)&lt;&#x2F;strong&gt; for any single transaction.&lt;&#x2F;li&gt;
&lt;li&gt;This cap applies regardless of the block gas limit set by miners or validators.&lt;&#x2F;li&gt;
&lt;li&gt;Transactions specifying gas limits higher than 16,777,216 gas will be rejected with an appropriate error code (e.g., &lt;code&gt;MAX_GAS_LIMIT_EXCEEDED&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;changes-to-evm-behavior&quot;&gt;Changes to EVM Behavior&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Txpool Validation&lt;&#x2F;strong&gt;: During transaction validation, if the &lt;code&gt;gasLimit&lt;&#x2F;code&gt; specified by the sender exceeds 16,777,216, the transaction is invalidated (not included in the txpool).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Block Validation&lt;&#x2F;strong&gt;: As part of block validation before processing, any block having a transaction with &lt;code&gt;gasLimit&lt;&#x2F;code&gt; &amp;gt; 16,777,216 is deemed invalid and rejected.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;protocol-adjustment&quot;&gt;Protocol Adjustment&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;GAS_LIMIT&lt;&#x2F;code&gt; parameter for transactions will be capped in client implementations at 16,777,216.&lt;&#x2F;li&gt;
&lt;li&gt;This cap is &lt;strong&gt;independent&lt;&#x2F;strong&gt; of the block gas limit, which exceeds this value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-16-777-216-2-24&quot;&gt;Why 16,777,216 (2^24)?&lt;&#x2F;h3&gt;
&lt;p&gt;The proposed cap of 16,777,216 gas (2^24) provides a clean power-of-two boundary that simplifies implementation while still being large enough to accommodate most complex transactions, including contract deployments and advanced DeFi interactions. This value represents approximately half of typical block sizes (30-40 million gas), ensuring multiple transactions can fit within each block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compatibility-with-current-gas-dynamics&quot;&gt;Compatibility with Current Gas Dynamics&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Backward Compatibility&lt;&#x2F;strong&gt;: Transactions with gas usage below 16,777,216 remain unaffected. Existing tooling and dApps need only minor updates to enforce the new cap.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Impact on Validators&lt;&#x2F;strong&gt;: Validators can continue to process blocks with a gas limit exceeding 16,777,216, provided individual transactions adhere to the cap.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This change is &lt;strong&gt;not backward-compatible&lt;&#x2F;strong&gt; with transactions that specify gas limits exceeding 16,777,216. Transactions with such high limits will need to be split into smaller operations. This adjustment is expected to impact a minimal number of users and dApps, as most transactions today fall well below the proposed cap.&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7825&#x2F;assets&#x2F;analysis&#x2F;&quot;&gt;empirical analysis&lt;&#x2F;a&gt; has been conducted to assess the potential impact of this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DoS Mitigation&lt;&#x2F;strong&gt;: A fixed cap reduces the risk of DoS attacks caused by excessively high-gas transactions.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Block Verification Stability&lt;&#x2F;strong&gt;: By capping individual transactions, the validation of blocks becomes more predictable and uniform.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Edge Cases&lt;&#x2F;strong&gt;: Certain highly complex transactions, such as large contract deployments, may require re-architecting to fit within the 16,777,216 gas cap.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Access Control Registry</title>
        <published>2024-11-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Shubham Khandelwal</name><uri>https://github.com/shubh-ta</uri>
	</author>
	
	<author>
		<name>Anushka Yadav</name><uri>https://github.com/anushka642000</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7820/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7820-access-control-registry/21764" />
        

        <id>https://wg-eips.ritovision.com/7820/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7820"
            label="ERC-7820" />
        

        
        

        
        <summary type="html">Registration, unregistration, role assignment, and role revocation for contracts, ensuring secure and transparent role management.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7820/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Access Control Registry (ACR) standard defines a universal interface for managing role-based access control across multiple smart contracts. This standard introduces a centralized registry system allowing access control management for multiple smart contracts. The single access-control registry smart contract manages the user roles across multiple contracts, and can be queryed for contract-specific role information. Additionally, the ACR standard provides functionality to grant and revoke roles for specific accounts, either individually or in bulk, ensuring that only authorized users can perform specific actions within a specific contract.&lt;&#x2F;p&gt;
&lt;p&gt;The core of the standard includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Registration and Unregistration&lt;&#x2F;strong&gt;: Contracts can register with the ACR, specifying an admin who can manage roles within the contract. Contracts can also be unregistered when they are no longer active.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Role Management&lt;&#x2F;strong&gt;: Admins can grant or revoke roles for accounts, either individually or in batches, ensuring fine-grained control over who can perform what actions within a contract.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Role Verification&lt;&#x2F;strong&gt;: Any account can verify if another account has a specific role in a registered contract, providing transparency and facilitating easier integration with other systems.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;By centralizing access control management, the ACR standard aims to reduce redundancy, minimize errors in access control logic, and provide a clear and standardized approach to role management across smart contracts. This improves security and maintainability, making it easier for developers to implement robust access control mechanisms in their applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As decentralized applications (dApps) grow in complexity, managing access control across multiple smart contracts becomes increasingly difficult.
Current practices involve bespoke implementations, leading to redundancy and potential security flaws. A standardized approach for managing roles and permissions will ensure better interoperability, security, and transparency. By providing a unified interface for registering contracts and managing roles, this standard simplifies development, ensures consistency and enhances security. It facilitates easier integration and auditing, fostering a more robust and interoperable ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;The advantages of using the provided system might be:&lt;&#x2F;p&gt;
&lt;p&gt;Structured smart contracts management via specialized contracts.
Ad-hoc access-control provision of a protocol.
Ability to specify custom access control rules to maintain the protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;AccessControlRegistry&lt;&#x2F;code&gt; contract provides a standardized interface for managing access control in Ethereum smart contracts. It includes functions to register and unregister contracts, grant and revoke roles for specific contracts, and check if an account has a particular role in a registered contract. Events are emitted for contract registration, unregistration, role grants, and role revocations, ensuring transparency and traceability of access control changes.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the AccessControlRegistry MUST reject the registration of zero addresses.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IAccessControlRegistry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a contract is registered.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _contract The address of the registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _admin The address of the admin for the registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractRegistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a contract is unregistered.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _contract The address of the unregistered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _admin The address who unregistered the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractUnregistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a role is granted to an account for a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param targetContract The address of the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param role The role being granted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param account The address of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleGranted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a role is revoked from an account for a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param targetContract The address of the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param role The role being revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param account The address of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Registers a contract with the given admin.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _admin The address of the admin for the registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _admin&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unregisters a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _contract The address of the contract to unregister.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unRegisterContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Grants roles to multiple accounts for multiple contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param targetContracts An array of contract addresses to which roles will be granted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param roles An array of roles to be granted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param accounts An array of accounts to be granted the roles.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContracts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accounts&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 class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revokes roles from multiple accounts for multiple contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param targetContracts An array of contract addresses from which roles will be revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param roles An array of roles to be revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param accounts An array of accounts from which the roles will be revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContracts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accounts&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 class=&quot;z-storage z-type&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;Gets the information of a registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;@param _contract The address of the contract to get the information.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;@return isActive Whether the contract is active.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;@return admin The address of the admin for the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;MUST revert if the registered contract doesn&amp;#39;t exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getContractInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isActive&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets the information of a registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param _contract The address of the contract to get the information.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @return isActive Whether the contract is active.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @return admin The address of the admin for the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the registered contract doesn&amp;#39;t exist`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRoleInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isActive&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; admin&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;IAccessControlRegistry&lt;&#x2F;code&gt; interface aims to provide a standardized way to manage access control across multiple contracts within the ecosystem. By defining a clear structure and set of events, this interface helps streamline the process of registering, unregistering, and managing roles for contracts. The rationale for each function and event is as follows:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-registration-and-unregistration&quot;&gt;Contract Registration and Unregistration&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;registerContract(address _admin)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: This function allows the registration of a new contract along with its admin address. This is crucial for initializing the access control settings for a contract and ensuring that there is an accountable admin who can manage roles and permissions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;unRegisterContract(address _contract)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: This function enables the removal of a contract from the registry. Unregistering a contract is important when a contract is no longer in use or needs to be decommissioned to prevent unauthorized access.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;role-management&quot;&gt;Role Management&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;grantRole(address[] memory targetContracts, bytes32[] memory roles, address[] memory accounts)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: This function allows the assignment of roles to multiple accounts for multiple contracts in a single transaction. This bulk operation is designed to reduce the gas costs and simplify the process of role assignment in large systems with numerous contracts and users.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;revokeRole(address[] memory targetContracts, bytes32[] memory roles, address[] memory accounts)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Similar to &lt;code&gt;grantRole&lt;&#x2F;code&gt;, this function facilitates the revocation of roles from multiple accounts across multiple contracts in a single transaction. This ensures efficient management of permissions, especially in scenarios where many users need their roles updated simultaneously.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;role-checking&quot;&gt;Role Checking&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;getRoleInfo(address targetContract, address account, bytes32 role)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: This view function allows the verification of whether a particular account holds a specific role for a given contract. This is essential for ensuring that operations requiring specific permissions are performed only by authorized users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-information-retrieval&quot;&gt;Contract Information Retrieval&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;getContractInfo(address _contract)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: This function provides the ability to retrieve the status and admin information of a registered contract. It enhances transparency and allows administrators and users to easily query the status and management of any contract within the registry.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ContractRegistered(address indexed _contract, address indexed _admin)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Emitted when a new contract is registered, this event ensures that there is a public record of contract registrations, facilitating auditability and transparency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ContractUnregistered(address indexed _contract, address indexed _admin)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Emitted when a contract is unregistered, this event serves to notify the system and its users of the removal of a contract from the registry, which is critical for maintaining an up-to-date and accurate registry.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;RoleGranted(address indexed targetContract, bytes32 indexed role, address indexed account)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Emitted when a role is granted to an account, this event provides a public log that can be used to track role assignments and changes, ensuring that role grants are transparent and verifiable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;RoleRevoked(address indexed targetContract, bytes32 indexed role, address indexed account)&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Emitted when a role is revoked from an account, this event similarly ensures that role revocations are publicly logged and traceable, supporting robust access control management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;register&lt;&#x2F;code&gt; function must be invoked from the registering smart contract.
The &lt;code&gt;grantRole&lt;&#x2F;code&gt; and &lt;code&gt;revokeRole&lt;&#x2F;code&gt; functions must be invoked either from the registered contract or the admin of the registered contract.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IAccessControlRegistry.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccessControlRegistry&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IAccessControlRegistry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Contains information about a registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param isActive Indicates whether the contract is active.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param admin The address of the admin for the registered contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; isActive&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; admin&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mapping to store information of registered contracts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ContractInfo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; contracts&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mapping to track roles assigned to accounts for specific contracts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; _contractRoles&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Custom error to handle duplicate registration attempts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractAlreadyRegistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Modifier to check if the caller is an admin or the contract itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyAdminOrContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;            _isAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Caller is not admin nor contract&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Modifier to check if the caller is an admin of the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;            _isAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Caller is not an admin&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Modifier to ensure the contract is active&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyActiveContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Contract not registered&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Modifier to validate if the provided address is non-zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Registers a contract with the given admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _admin: Address of the admin to register&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _admin&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_admin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; _contract &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if the contract is already registered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ContractInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; contractInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;contractInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractAlreadyRegistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Register the contract with the provided admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        contractInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        contractInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;admin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _admin&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractRegistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _admin&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unregisters a contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _contract: Address of the contract to unregister&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unRegisterContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        onlyAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        onlyActiveContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ContractInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; contractInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&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&gt;        contractInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        contractInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;admin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContractUnregistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Grants roles to multiple accounts for multiple contracts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; targetContracts: Array of contract addresses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; roles: Array of roles to grant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; accounts: Array of accounts to assign the roles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContracts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accounts&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 class=&quot;z-storage z-type&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 class=&quot;z-keyword&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&gt;            targetContracts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Array lengths do not match&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&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; cachedArrayLength &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Grant roles in a batch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; cachedArrayLength&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revokes roles from multiple accounts for multiple contracts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; targetContracts: Array of contract addresses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; roles: Array of roles to revoke&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; accounts: Array of accounts from which roles are revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContracts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accounts&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 class=&quot;z-storage z-type&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 class=&quot;z-keyword&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&gt;            targetContracts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Array lengths do not match&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&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; cachedArrayLength &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revoke roles in a batch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; cachedArrayLength&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            _revokeRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves information of a registered contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _contract: Address of the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns: isActive status and admin address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getContractInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;        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 class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isActive&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; admin&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ContractInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; info &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;info&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isActive&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; info&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;admin&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets role information for an account and contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; targetContract: Address of the target contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; account: Address of the account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; role: Role identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns: Boolean indicating if the account has the role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRoleInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; role&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _contractRoles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;role&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Internal function to grant a role to an account for a contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt;        internal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        onlyAdminOrContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        onlyActiveContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        validAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;account&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _contractRoles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;role&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleGranted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; account&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Internal function to revoke a role from an account for a contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _revokeRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt;        internal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        onlyAdminOrContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        onlyActiveContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        validAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;account&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            _contractRoles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;role&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Role already revoked&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _contractRoles&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;role&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; role&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; account&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks if the caller is an admin for the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _contract: Address of the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _admin: Address of the admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns: Boolean indicating admin status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _isAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _admin&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _admin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; contracts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;admin&lt;&#x2F;span&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;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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;design-decisions&quot;&gt;Design Decisions&lt;&#x2F;h3&gt;
&lt;p&gt;There are a few design decisions that have to be explicitly specified to ensure the functionality, security, and efficiency of the &lt;code&gt;IAccessControlRegistry&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;decentralized-contract-registration&quot;&gt;Decentralized Contract Registration&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;No Central Owner&lt;&#x2F;strong&gt;: There is no central owner who can register contracts. This design choice promotes decentralization and ensures that individual contracts are responsible for their own registration and management.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;efficient-storage-and-lookup&quot;&gt;Efficient Storage and Lookup&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Mapping Utilization&lt;&#x2F;strong&gt;: The use of mappings for storing contract information (&lt;code&gt;mapping(address =&amp;gt; ContractInfo) private contracts&lt;&#x2F;code&gt;) and role assignments (&lt;code&gt;mapping(address =&amp;gt; mapping(address =&amp;gt; mapping(bytes32 =&amp;gt; bool))) private _contractRoles&lt;&#x2F;code&gt;) ensures efficient storage and lookup. This is crucial for maintaining performance in a large-scale system with numerous contracts and roles.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;role-management-flexibility&quot;&gt;Role Management Flexibility&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Bulk Operations&lt;&#x2F;strong&gt;: Functions like &lt;code&gt;grantRole&lt;&#x2F;code&gt; and &lt;code&gt;revokeRole&lt;&#x2F;code&gt; allow for the assignment and revocation of roles to multiple accounts for multiple contracts in a single transaction. This bulk operation reduces gas costs and simplifies the process of role management in large systems.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;robust-security-measures&quot;&gt;Robust Security Measures&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Admin-Only Operations&lt;&#x2F;strong&gt;: Functions that modify the state, such as unRegisterContract, &lt;code&gt;_grantRole&lt;&#x2F;code&gt;, and &lt;code&gt;_revokeRole&lt;&#x2F;code&gt;, are restricted to contract admins. This ensures that only authorized personnel can manage contracts and roles, reducing the risk of unauthorized changes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Valid Address Checks&lt;&#x2F;strong&gt;: The &lt;code&gt;validAddress&lt;&#x2F;code&gt; modifier ensures that addresses are non-zero, preventing potential issues with null addresses which could lead to unintended behavior or security vulnerabilities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Active Contract Checks&lt;&#x2F;strong&gt;: The &lt;code&gt;onlyActiveContract&lt;&#x2F;code&gt; modifier ensures that actions are only performed on active or registered contracts, preventing operations on inactive or unregistered contracts.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;transparent-auditing&quot;&gt;Transparent Auditing&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Event Logging&lt;&#x2F;strong&gt;: Emitting events for each significant action (registration, unregistration, role granting, and revocation) provides a transparent log that can be monitored and audited. This helps in detecting and responding to unauthorized or suspicious activities promptly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;AccessControlRegistry&lt;&#x2F;code&gt; implements several security measures to ensure the integrity and reliability of the access control system:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Admin-Only Restrictions&lt;&#x2F;strong&gt;: By limiting state-modifying functions to contract admins, the system prevents unauthorized users from making critical changes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Active Contract Checks&lt;&#x2F;strong&gt;: Operations are restricted to active contracts, reducing the risk of interacting with deprecated or unregistered contracts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Event Logging&lt;&#x2F;strong&gt;: Comprehensive event logging supports transparency and auditability, allowing for effective monitoring and detection of unauthorized actions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Expirable ERC-20</title>
        <published>2024-11-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>sirawt</name><uri>https://github.com/MASDXI</uri>
	</author>
	
	<author>
		<name>ADISAKBOONMARK</name><uri>https://github.com/ADISAKBOONMARK</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7818/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7818-expirable-erc20/21655" />
        

        <id>https://wg-eips.ritovision.com/7818/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:7818"
            label="ERC-7818" />
        

        
        

        
        <summary type="html">An ERC-20 extension for creating fungible tokens with expiration, supporting time-limited use cases.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7818/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduces an extension for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens, which facilitates the implementation of an expiration mechanism. Through this extension, tokens have a predetermined validity period, after which they become invalid and can no longer be transferred or used. This functionality proves beneficial in scenarios such as time-limited bonds, loyalty rewards, or game tokens necessitating automatic invalidation after a specific duration. The extension is crafted to seamlessly align with the existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard, ensuring smooth integration with the prevailing token smart contract while introducing the capability to govern and enforce token expiration at the contract level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This extension facilitates the development of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard compatible tokens featuring expiration dates. This capability broadens the scope of potential applications, particularly those involving time-sensitive assets. Expirable tokens are well-suited for scenarios necessitating temporary validity, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bonds or financial instruments with defined maturity dates&lt;&#x2F;li&gt;
&lt;li&gt;Time-constrained assets within gaming ecosystems&lt;&#x2F;li&gt;
&lt;li&gt;Next-gen loyalty programs incorporating expiring rewards or points&lt;&#x2F;li&gt;
&lt;li&gt;Prepaid credits for utilities or services (e.g., cashback, data packages, fuel, computing resources) that expire if not used within a specified time frame&lt;&#x2F;li&gt;
&lt;li&gt;Postpaid telecom data package allocations that expire at the end of the billing cycle, motivating users to utilize their data before it resets&lt;&#x2F;li&gt;
&lt;li&gt;Tokenized e-Money for a closed-loop ecosystem, such as transportation, food court, and retail payments&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;epoch-mechanism&quot;&gt;Epoch Mechanism&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Epochs&lt;&#x2F;strong&gt; represent a specific period or block range during which certain tokens are valid. They can be categorized into two types&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;block-based&lt;&#x2F;strong&gt; Defined by a specific number of blocks (e.g., 1000 &lt;code&gt;blocks&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;time-based&lt;&#x2F;strong&gt; Defined by a specific duration in seconds (e.g., 1000 &lt;code&gt;seconds&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Tokens linked to an &lt;code&gt;epoch&lt;&#x2F;code&gt; remain valid as long as the &lt;code&gt;epoch&lt;&#x2F;code&gt; is active. Once the specified number of &lt;code&gt;blocks&lt;&#x2F;code&gt; or the duration in &lt;code&gt;seconds&lt;&#x2F;code&gt; has passed, the &lt;code&gt;epoch&lt;&#x2F;code&gt; expires, and any tokens associated with it are considered expired.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;balance-look-back-over-epochs&quot;&gt;Balance Look Back Over Epochs&lt;&#x2F;h3&gt;
&lt;p&gt;To retrieve the usable balance, tokens are checked from the &lt;strong&gt;current epoch&lt;&#x2F;strong&gt; against a &lt;strong&gt;past epoch&lt;&#x2F;strong&gt; (which can be any &lt;em&gt;&lt;strong&gt;n&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; epochs back). The past epoch can be set to any value &lt;em&gt;&lt;strong&gt;n&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;, allowing flexibility in tracking and summing tokens that are still valid from previous epochs, up to &lt;em&gt;&lt;strong&gt;n&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; epochs back.&lt;&#x2F;p&gt;
&lt;p&gt;The usable balance is the sum of tokens valid between the &lt;strong&gt;current epoch&lt;&#x2F;strong&gt; and the &lt;strong&gt;past epoch&lt;&#x2F;strong&gt;, ensuring that only non-expired tokens are considered.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-scenario&quot;&gt;Example Scenario&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;epoch&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;strong&gt;balance&lt;&#x2F;strong&gt;&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&lt;&#x2F;td&gt;&lt;td&gt;150&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current Epoch&lt;&#x2F;strong&gt;: 3&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Past Epoch&lt;&#x2F;strong&gt;: 1 epoch back&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Usable Balance&lt;&#x2F;strong&gt;: 350&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Tokens from &lt;strong&gt;Epoch 2&lt;&#x2F;strong&gt; and &lt;strong&gt;Epoch 3&lt;&#x2F;strong&gt; are valid. The same logic applies for any &lt;em&gt;&lt;strong&gt;n&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; epochs back, where the usable balance includes tokens from the current epoch and all prior valid epochs.&lt;&#x2F;p&gt;
&lt;p&gt;Compatible implementations &lt;strong&gt;MUST&lt;&#x2F;strong&gt; inherit from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s interface and &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have all the following functions and all function behavior &lt;strong&gt;MUST&lt;&#x2F;strong&gt; meet the specification.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7818 interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for adding expirable functionality to ERC20 tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7818&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enum represents the types of `epoch` that can be used.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The implementing contract may use one of these types to define how the `epoch` is measured.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EPOCH_TYPE&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        BLOCKS_BASED&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; measured in the number of blocks (e.g., 1000 blocks)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        TIME_BASED&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; measured in seconds (UNIX time) (e.g., 1000 seconds)&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the balance of a specific `epoch` owned by an account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch for which the balance is checked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The balance of the specified `epoch`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;MUST&amp;quot; return 0 if the specified `epoch` is expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOfAtEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the latest epoch currently tracked by the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The latest epoch of the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; currentEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the duration of a single epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The duration of a single epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unit of the epoch length is determined by the `validityPeriodType` function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; epochLength&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the type of the epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; EPOCH_TYPE&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Enum value indicating the unit of an epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; epochType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;EPOCH_TYPE&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the validity duration in `epoch` counts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The validity duration in `epoch` counts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validityDuration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a specific `epoch` is expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch` to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the token is expired, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Implementing contracts &amp;quot;MUST&amp;quot; define and document the logic for determining expiration,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * typically by comparing the latest epoch with the given `epoch` value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * based on the `EPOCH_TYPE` measurement (e.g., block count or time duration).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isEpochExpired&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers a specific `epoch` and value to a recipient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch` for the transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount to transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the transfer succeeded, otherwise false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAtEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers a specific `epoch` and value from one account to another.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch` for the transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The sender&amp;#39;s address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount to transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the transfer succeeded, otherwise false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFromAtEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;behavior-specification&quot;&gt;Behavior Specification&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the total balance of tokens held by an account that are still valid (i.e., have not expired). This includes any tokens associated with specific epochs, provided they remain within their validity duration. Expired tokens &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be included in the returned balance, ensuring that only actively usable tokens are reflected in the result.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;balanceOfAtEpoch&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the balance of tokens held by an account at the specified &lt;code&gt;epoch&lt;&#x2F;code&gt;. If the specified epoch is expired, this function &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return &lt;code&gt;0&lt;&#x2F;code&gt;.
For example, if &lt;code&gt;epoch&lt;&#x2F;code&gt; 5 has expired, calling &lt;code&gt;balanceOfByEpoch(5, address)&lt;&#x2F;code&gt; returns &lt;code&gt;0&lt;&#x2F;code&gt; even if there were tokens previously held in that epoch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;currentEpoch&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the current &lt;code&gt;epoch&lt;&#x2F;code&gt; of the contract.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;epochLength&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return duration between &lt;code&gt;epoch&lt;&#x2F;code&gt; in blocks or time in seconds.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;epochType&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the type of epoch used by the contract, which can be either &lt;code&gt;BLOCKS_BASED&lt;&#x2F;code&gt; or &lt;code&gt;TIME_BASED&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;validityDuration&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the validity duration of tokens in terms of &lt;code&gt;epoch&lt;&#x2F;code&gt; counts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;isEpochExpired&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return true if the given &lt;code&gt;epoch&lt;&#x2F;code&gt; is expired, otherwise &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; exclusively transfer tokens that remain non-expired at the time of the transaction. Attempting to transfer expired tokens &lt;strong&gt;MUST&lt;&#x2F;strong&gt; revert the transaction or return &lt;code&gt;false&lt;&#x2F;code&gt;. Additionally, implementations &lt;strong&gt;MAY&lt;&#x2F;strong&gt; include logic to prioritize the automatic transfer of tokens closest to expiration, ensuring that the earliest expiring tokens are used first, provided they meet the non-expired condition.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;transferAtEpoch&lt;&#x2F;code&gt; and &lt;code&gt;transferFromAtEpoch&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; transfer the specified number of tokens held by an account at the specified epoch to the recipient, If the epoch has expired, the transaction &lt;strong&gt;MUST&lt;&#x2F;strong&gt; &lt;code&gt;revert&lt;&#x2F;code&gt; or return &lt;code&gt;false&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;totalSupply&lt;&#x2F;code&gt; &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be set to &lt;code&gt;0&lt;&#x2F;code&gt; or &lt;code&gt;type(uint256).max&lt;&#x2F;code&gt; due to the challenges of tracking only valid (non-expired) tokens.&lt;&#x2F;li&gt;
&lt;li&gt;The implementation &lt;strong&gt;MAY&lt;&#x2F;strong&gt; use a standardized custom error, such as &lt;code&gt;ERC7818TransferredExpiredToken&lt;&#x2F;code&gt; or &lt;code&gt;ERC7818TransferredExpiredToken(address sender, uint256 epoch)&lt;&#x2F;code&gt;, to clearly indicate that the operation failed due to attempting to transfer expired tokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;additional-potential-useful-function&quot;&gt;Additional Potential Useful Function&lt;&#x2F;h3&gt;
&lt;p&gt;These &lt;strong&gt;OPTIONAL&lt;&#x2F;strong&gt; functions provide additional functionality that might be useful depending on the specific use case.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getEpochBalance&lt;&#x2F;code&gt; returns the amount of tokens stored in a given &lt;code&gt;epoch&lt;&#x2F;code&gt;, even if the &lt;code&gt;epoch&lt;&#x2F;code&gt; has expired.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getEpochInfo&lt;&#x2F;code&gt; returns both the start and end of the specified &lt;code&gt;epoch&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getNearestExpiryOf&lt;&#x2F;code&gt; returns the token amount closest to expiration, along with an estimated expiration block number or timestamp based on &lt;code&gt;epochType&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getRemainingDurationBeforeEpochChange&lt;&#x2F;code&gt; returns the remaining time or blocks before the &lt;code&gt;epoch&lt;&#x2F;code&gt; change happens, based on the &lt;code&gt;epochType&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Although the term &lt;code&gt;epoch&lt;&#x2F;code&gt; is an abstract concept, it leaves room for various implementations. For example, epochs can support more granular tracking of tokens within each epoch, allowing for greater control over when tokens are valid or expired on-chain. Alternatively, epochs can support bulk expiration, where all tokens within the same epoch expire simultaneously. This flexibility enables different methods of tracking token expiration, depending on the specific needs of the use case.
&lt;code&gt;epoch&lt;&#x2F;code&gt; also introduces a &quot;lazy&quot; way to simplify token expiration tracking in a flexible and gas-efficient manner. Instead of continuously updating the expiration state with &lt;code&gt;write&lt;&#x2F;code&gt; operations by the user or additional services, the current epoch can be calculated using a &lt;code&gt;read&lt;&#x2F;code&gt; operation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;For reference implementation can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7818&#x2F;assets&#x2F;README&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;, But in the reference implementation, we employ a sorted list to automatically select the token that nearest expires first with a First-In-First-Out (&lt;code&gt;FIFO&lt;&#x2F;code&gt;) and sliding window algorithm that operates based on the &lt;code&gt;block.number&lt;&#x2F;code&gt; as opposed to relying on &lt;code&gt;block.timestamp&lt;&#x2F;code&gt;, which has been criticized for its lack of security and resilience, particularly given the increasing usage of Layer 2 (L2) networks over Layer 1 (L1) networks. Many L2 networks exhibit centralization and instability, which directly impacts asset integrity, rendering them potentially unusable during periods of network halting, as they are still reliant on the timestamp.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;denial-of-service&quot;&gt;Denial Of Service&lt;&#x2F;h3&gt;
&lt;p&gt;Run out of gas problem due to the operation consuming higher gas if transferring multiple groups of small tokens or loop transfer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-limit-vulnerabilities&quot;&gt;Gas Limit Vulnerabilities&lt;&#x2F;h3&gt;
&lt;p&gt;Exceeds block gas limit if the blockchain has a block gas limit lower than the gas used in the transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-values-as-a-proxy-for-time&quot;&gt;Block values as a proxy for time&lt;&#x2F;h3&gt;
&lt;p&gt;if using &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; for calculating &lt;code&gt;epoch&lt;&#x2F;code&gt; and In rare network halts, block production stops, freezing &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; and disrupting time-based logic. This risks asset integrity and inconsistent states.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fairness-concerns&quot;&gt;Fairness Concerns&lt;&#x2F;h3&gt;
&lt;p&gt;In a straightforward implementation, where all tokens within the same epoch share the same expiration (e.g., at &lt;code&gt;epoch&lt;&#x2F;code&gt;:&lt;code&gt;x&lt;&#x2F;code&gt;), bulk expiration occurs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;risks-in-liquidity-pools&quot;&gt;Risks in Liquidity Pools&lt;&#x2F;h3&gt;
&lt;p&gt;When tokens with expiration dates are deposited into liquidity pools (e.g., in DEXs), they may expire while still in the pool.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Set upper bounds for MODEXP</title>
        <published>2024-11-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Radoslaw Zagorowicz</name><uri>https://github.com/rodiazet</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7823/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7823-set-upper-bounds-for-modexp/21798" />
        

        <id>https://wg-eips.ritovision.com/7823/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:7823"
            label="EIP-7823" />
        

        
        

        
        <summary type="html">Each input field is restricted to a maximum of 8192 bits</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7823/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce an upper bound on the inputs of the MODEXP precompile. This can reduce the number of potential bugs, because the testing surface is not infinite anymore, and makes it easier to be replaced using EVMMAX.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The MODEXP precompile has been a source of numerous consensus bugs. Many of them were due to specifically crafted cases using impractical input lengths.&lt;&#x2F;p&gt;
&lt;p&gt;Its pricing function is also quite complex given its nature of unbounded inputs. While we don&#x27;t suggest to rework the pricing function, it may be possible in a future upgrade once the limits are in place.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore this limitation makes it more feasible to have the precompile replaced with EVM code through features like EVMMAX.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Recap from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;At address &lt;code&gt;0x00……05&lt;&#x2F;code&gt;, add a precompile that expects input in the following format:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;length_of_BASE&amp;gt; &amp;lt;length_of_EXPONENT&amp;gt; &amp;lt;length_of_MODULUS&amp;gt; &amp;lt;BASE&amp;gt; &amp;lt;EXPONENT&amp;gt; &amp;lt;MODULUS&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We introduce an upper bound to the inputs of the precompile, each of the length inputs (&lt;code&gt;length_of_BASE&lt;&#x2F;code&gt;, &lt;code&gt;length_of_EXPONENT&lt;&#x2F;code&gt; and &lt;code&gt;length_of_MODULUS&lt;&#x2F;code&gt;) MUST be less than or equal to 8192 bits (1024 bytes).&lt;&#x2F;p&gt;
&lt;p&gt;If any of these inputs are larger than the limit, the precompile execution stops, returns an error, and consumes all gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;limit&quot;&gt;Limit&lt;&#x2F;h3&gt;
&lt;p&gt;This upper bound allows the existing use cases of MODEXP:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;RSA verification with up to 8192 bit keys. Commonly used ones are 1024&#x2F;2048&#x2F;4096 bits.&lt;&#x2F;li&gt;
&lt;li&gt;Elliptic curve related use cases are usually less than 384 bits.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;evmmax&quot;&gt;EVMMAX&lt;&#x2F;h3&gt;
&lt;p&gt;Replacing the precompile with EVM code using an instruction set like EVMMAX would be made simpler with this limit: Common cases (256, 381, 1024, 2048) could be implemented in special fast paths, while a slow fallback could be provided for the rest. Or even special, frequently used, moduli could have their own paths.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore one could consider limiting the lengths to certain inputs only.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;analysis&quot;&gt;Analysis&lt;&#x2F;h3&gt;
&lt;p&gt;Since MODEXP was introduced in the Byzantium hard fork, an analysis has been conducted between block 5472266 (April 20, 2018) and block 21550926 (January 4th, 2025). All lengths of inputs are expressed in bytes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;base-length-occurrences&quot;&gt;Base length occurrences&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;code&gt;input_of_BASE&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th&gt;count&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;2439595&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;128&lt;&#x2F;td&gt;&lt;td&gt;4167&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;256&lt;&#x2F;td&gt;&lt;td&gt;2969&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;160&lt;&#x2F;td&gt;&lt;td&gt;436&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;512&lt;&#x2F;td&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;513&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;129&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;385&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;exponent-length-occurrences&quot;&gt;Exponent length occurrences&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;code&gt;input_of_EXPONENT&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th&gt;count&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;2442255&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;4771&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;159&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;128&lt;&#x2F;td&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;modulo-length-occurrences&quot;&gt;Modulo length occurrences&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;code&gt;input_of_MODULUS&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th&gt;count&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;2439594&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;128&lt;&#x2F;td&gt;&lt;td&gt;4167&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;256&lt;&#x2F;td&gt;&lt;td&gt;2968&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;160&lt;&#x2F;td&gt;&lt;td&gt;436&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;512&lt;&#x2F;td&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;129&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;384&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;257&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;This shows that no past successful use case exceeded an input length of 513 bytes, and the majority uses 32&#x2F;128&#x2F;256 byte inputs.&lt;&#x2F;p&gt;
&lt;p&gt;Besides these, there were a few invocations with invalid inputs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Empty inputs&lt;&#x2F;li&gt;
&lt;li&gt;Inputs consisting of only &lt;code&gt;0x9e5faafc&lt;&#x2F;code&gt; or &lt;code&gt;0x85474728&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A large, but invalid input: &lt;code&gt;0x9e281a98000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021e19e0c9bab2400000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is a backwards incompatible change. However, based on analysis until block 21550926 (see above), no past transaction would have behaved differently after this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Since only the accepted input range is reduced, no new security surface area is expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Wrapping of bubbled up reverts</title>
        <published>2024-08-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Daniel Gretzke</name><uri>https://github.com/gretzke</uri>
	</author>
	
	<author>
		<name>Sara Reynolds</name><uri>https://github.com/snreynolds</uri>
	</author>
	
	<author>
		<name>Alice Henshaw</name><uri>https://github.com/hensha256</uri>
	</author>
	
	<author>
		<name>Marko Veniger</name><email>marko.veniger@tenderly.co</email>
	</author>
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7751/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7751-wrapping-of-bubbled-up-reverts/20740" />
        

        <id>https://wg-eips.ritovision.com/7751/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7751"
            label="ERC-7751" />
        

        
        

        
        <summary type="html">Handling bubbled up reverts using custom errors with additional context</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7751/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using a dedicated custom error. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The &lt;code&gt;WrappedError&lt;&#x2F;code&gt; custom error should wrap reverts from called contracts and provide a consistent interface for parsing and handling reverts in tools like Etherscan or Tenderly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, when a smart contract calls another and the called contract reverts, the revert reason is usually bubbled up and thrown as is. This can make it more difficult to tell which context the error came from. By standardizing the use of custom errors with additional context, more meaningful and informative revert reasons can be provided. This will improve the debugging experience and make it easier for developers and infrastructure providers like Etherscan to display accurate stack traces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;In order to wrap a revert, a contract MUST revert with the following error that corresponds to the following signature &lt;code&gt;0x90bfb865&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; details&lt;&#x2F;span&gt;&lt;span&gt;)&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;Where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;target&lt;&#x2F;code&gt; is the address of the called contract that reverted.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;selector&lt;&#x2F;code&gt; is the selector of the called function that reverted. If the call was an ETH transfer without any data, the selector MUST be &lt;code&gt;bytes4(0)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;reason&lt;&#x2F;code&gt; is the raw bytes of the revert reason.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;details&lt;&#x2F;code&gt; is optional additional context about the revert. In cases where no additional context is needed, the &lt;code&gt;details&lt;&#x2F;code&gt; bytes can be empty. In cases with additional context, the &lt;code&gt;details&lt;&#x2F;code&gt; bytes MUST be an ABI encoded custom error declared on the contract that emits the &lt;code&gt;WrappedError&lt;&#x2F;code&gt; error.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;By including the called contract and function, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC does not introduce any backwards incompatibilities. Existing contracts can adopt this standard incrementally.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balanceOf&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;    Token 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; details&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20TransferFailed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; recipient&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; token_&lt;&#x2F;span&gt;&lt;span&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&gt;        token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ERC20TransferFailed&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Router&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Vault 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; details&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Vault&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vault_&lt;&#x2F;span&gt;&lt;span&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&gt;        vault &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; vault&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vault&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vault&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdraw&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Test&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; test_BubbledNestedReverts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        Token token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        Vault vault &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Vault&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span&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&gt;        Router router &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Router&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vault&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; router&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; thrownError&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; expectedError &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;                Router&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;WrappedError&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;vault&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vault&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdraw&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;                    Vault&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;WrappedError&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                    address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span&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&gt;                    token&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;                    abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Error(string)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;                    abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Vault&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ERC20TransferFailed&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&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&gt;                )&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;thrownError&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;expectedError&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;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;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;When catching a revert from a called contract, the calling contract should revert with a custom error following the above conventions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Foo&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; details&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MyCustomError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; logic&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 class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; returnData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WrappedError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; returnData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;MyCustomError&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Smart contracts could either drop or purposefully suppress the bubbled up reverts along the revert chain. Additionally, smart contracts may also lie or incorrectly report the wrapped reverts, so the information is not guaranteed to be accurate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multi-Owner Non-Fungible Tokens (MO-NFT)</title>
        <published>2024-07-13T00:00:00+00:00</published>
        <updated>2026-04-25T12:06:20+00:00</updated>
	
	
	<author>
		<name>Cheng Qian</name><uri>https://github.com/jamesavechives</uri><email>james.walstonn@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7743/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/discussion-on-eip-7743-multi-owner-non-fungible-tokens-mo-nft/20577" />
        

        <id>https://wg-eips.ritovision.com/7743/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:7743"
            label="ERC-7743" />
        

        
        

        
        <summary type="html">Non-fungible token that supports multiple owners, allowing shared ownership and transferability among users.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7743/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC proposes a new standard for non-fungible tokens (NFTs) that supports multiple owners. The MO-NFT standard allows a single NFT to have multiple owners, reflecting the shared and distributable nature of digital assets. This model incorporates mechanisms for provider-defined transfer fees and ownership archiving, enabling flexible and collaborative ownership structures. It maintains compatibility with the existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard to ensure interoperability with current tools and platforms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Traditional NFTs enforce a single-ownership model, which does not align with the inherent duplicability and collaborative potential of digital assets. MO-NFTs allow for shared ownership, promoting wider distribution and collaboration while maintaining secure access control. The inclusion of provider fees and ownership archiving enhances the utility and flexibility of NFTs in representing digital assets and services.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;token-creation-and-ownership-model&quot;&gt;Token Creation and Ownership Model&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minting&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The function &lt;code&gt;mintToken()&lt;&#x2F;code&gt; allows the creation of a new MO-NFT. The caller becomes both the initial owner and the provider of the token.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mintToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A new &lt;code&gt;tokenId&lt;&#x2F;code&gt; is generated, and the caller is added to the owners set and recorded as the provider. The &lt;code&gt;balanceOf&lt;&#x2F;code&gt; the caller is incremented.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ownership List&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The MO-NFT maintains a list of owners for each token. Owners are stored in an enumerable set to prevent duplicates and allow efficient lookup.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provider Role&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The provider is the initial owner who can set and update the &lt;code&gt;transferValue&lt;&#x2F;code&gt; fee. Only the provider can modify certain token parameters.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transfer Mechanism&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Owners can transfer the token to new owners using &lt;code&gt;transferFrom&lt;&#x2F;code&gt;. The transfer adds the new owner to the list without removing existing owners and transfers the &lt;code&gt;transferValue&lt;&#x2F;code&gt; fee to the provider.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;transfer-of-ownership&quot;&gt;Transfer of Ownership&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Additive Ownership&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Transferring ownership adds the new owner to the ownership list without removing current owners. This approach reflects the shared nature of digital assets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provider Fee Handling&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;During a transfer, the specified &lt;code&gt;transferValue&lt;&#x2F;code&gt; fee is transferred to the provider. The contract must have sufficient balance to cover this fee.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Archiving Ownership&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Owners can mark themselves as archived for a specific token, meaning they can no longer transfer that token. Once set, this status cannot be reversed. And for Digital Asset platform, this status means the owner can download the real digital asset directly; if it is not archived, then it must be changed to archived first, then owner can download the real digital asset.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; archive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;interface-definitions&quot;&gt;Interface Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Minting Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function mintToken() public onlyOwner returns (uint256);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function provide(string memory assetName, uint256 size, bytes32 fileHash, address provider, uint256 transferValue) external returns (uint256);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Transfer Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function transferFrom(address from, address to, uint256 tokenId) public;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function safeTransferFrom(address from, address to, uint256 tokenId) public;&lt;&#x2F;code&gt; &lt;em&gt;(Disabled or overridden)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;&lt;&#x2F;code&gt; &lt;em&gt;(Disabled or overridden)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Ownership Management Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function isOwner(uint256 tokenId, address account) public view returns (bool);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function getOwnersCount(uint256 tokenId) public view returns (uint256);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function balanceOf(address owner) external view returns (uint256 balance);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;function ownerOf(uint256 tokenId) external view returns (address owner);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Provider Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function setTransferValue(uint256 tokenId, uint256 newTransferValue) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Archived Status Function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function archive(uint256 tokenId) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event TokenMinted(uint256 indexed tokenId, address indexed owner);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event TokenTransferred(uint256 indexed tokenId, address indexed from, address indexed to);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event TransferValueUpdated(uint256 indexed tokenId, uint256 oldTransferValue, uint256 newTransferValue);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;event ArchivedStatusUpdated(uint256 indexed tokenId, address indexed owner, bool archived);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;erc-721-compliance&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; Compliance&lt;&#x2F;h3&gt;
&lt;p&gt;The MO-NFT standard is designed to be compatible with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard. It implements required functions such as &lt;code&gt;balanceOf&lt;&#x2F;code&gt;, &lt;code&gt;ownerOf&lt;&#x2F;code&gt;, and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; from the &lt;code&gt;ERC721&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Approval Functions&lt;&#x2F;strong&gt;: Functions like &lt;code&gt;approve&lt;&#x2F;code&gt;, &lt;code&gt;getApproved&lt;&#x2F;code&gt;, &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt;, and &lt;code&gt;isApprovedForAll&lt;&#x2F;code&gt; are intentionally disabled or overridden, as they do not align with the MO-NFT multi-owner model.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Safe Transfer Functions&lt;&#x2F;strong&gt;: The &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; functions are restricted because traditional ERC-721 transfer safety checks are not applicable when ownership is additive rather than exclusive.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Supports Interface&lt;&#x2F;strong&gt;: The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function ensures that the MO-NFT declares compatibility with the ERC-721 standard, allowing it to be integrated with existing tools and platforms.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC165&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Multi-Ownership Model&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Digital assets are inherently duplicable and can be shared without loss of quality. The multi-owner model allows broader distribution and collaboration while maintaining a unique token identity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Additive Ownership&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;By adding new owners without removing existing ones, we support shared ownership models common in collaborative environments and digital content distribution.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provider Fee Mechanism&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Incorporating a provider fee incentivizes creators and providers by rewarding them whenever the asset is transferred. This aligns with models where creators receive royalties or fees for their work.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ownership Archiving&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Allowing owners to archive themselves from the ownership list provides flexibility, enabling owners to relinquish rights or prevent further transfers of the asset. This replaces the previous concept of &quot;burning&quot; ownership.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ERC-721 Compatibility&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Maintaining compatibility with ERC-721 allows MO-NFTs to leverage existing infrastructure, tools, and platforms, facilitating adoption and interoperability.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;While the MO-NFT standard aims to maintain compatibility with ERC-721, certain deviations are necessary due to the multi-owner model:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Disabling Approvals Functions&lt;&#x2F;strong&gt;: Traditional ERC-721 approvals assume that a single owner has the right to grant or revoke approvals. In MO-NFT, a token can have multiple owners. Without a protocol-defined mechanism for “co-ownership consensus,” an approval system would open the door to an unintentional or unwanted transfer if only one co-owner granted approval. We felt this approach could undermine the shared-ownership model, so the reference implementation chooses to revert calls to approval-related functions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This may limit compatibility with existing NFT platforms and marketplaces that rely on approve or setApprovalForAll. In principle, developers could extend the MO-NFT standard with more advanced “multi-signature” or “consensus-based” approvals, but that is beyond the scope of this initial EIP. Our goal is to keep the core standard minimal and avoid confusion for marketplaces that were built with single-owner assumptions.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Safe Transfer Functions&lt;&#x2F;strong&gt;: The “safe” variants of ERC-721 transfers (safeTransferFrom) serve to protect tokens from being accidentally sent to non-compliant contracts. Because MO-NFT’s multi-owner approach does not inherently break the logic of “checking whether the recipient can handle ERC-721 tokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Implementing “safe” in the same manner as ERC-721: after a new owner is added, check &lt;code&gt;onERC721Received&lt;&#x2F;code&gt; on the recipient contract.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ownerOf&lt;&#x2F;code&gt; Function&lt;&#x2F;strong&gt;: Returns the first owner in the owners list for compatibility, but the concept of a single owner does not fully apply.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Developers should be aware of these differences when integrating MO-NFTs into systems designed for standard ERC-721 tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minting an MO-NFT and Verifying Initial Ownership&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;mintToken()&lt;&#x2F;code&gt; as the provider.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Output&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A new &lt;code&gt;tokenId&lt;&#x2F;code&gt; is generated.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The caller is added as the first owner.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;balanceOf&lt;&#x2F;code&gt; the caller increases by 1.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The provider is recorded for the token.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TokenMinted&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transferring an MO-NFT and Verifying Provider Fee Transfer&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;transferFrom(from, to, tokenId)&lt;&#x2F;code&gt; where &lt;code&gt;from&lt;&#x2F;code&gt; is an existing owner and &lt;code&gt;to&lt;&#x2F;code&gt; is a new address.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Output&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;to&lt;&#x2F;code&gt; address is added to the owners list.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;transferValue&lt;&#x2F;code&gt; fee is transferred to the provider.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;balanceOf&lt;&#x2F;code&gt; of the &lt;code&gt;to&lt;&#x2F;code&gt; address increases by 1.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TokenTransferred&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Archiving Ownership&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An owner calls &lt;code&gt;archive(tokenId)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Output&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The owner’s transfer ability for that token is archived.&lt;&#x2F;li&gt;
&lt;li&gt;The owner can no longer transfer that token.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ArchivedStatusUpdated&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting Transfer Value&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The provider calls &lt;code&gt;setTransferValue(tokenId, newTransferValue)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Output&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;transferValue&lt;&#x2F;code&gt; is updated in the contract.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TransferValueUpdated&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Failing Transfer to Existing Owner&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Attempt to &lt;code&gt;transferFrom&lt;&#x2F;code&gt; to an address that is already an owner.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Output&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The transaction reverts with the error &lt;code&gt;&quot;MO-NFT: Recipient is already an owner&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;No changes to ownership or balances occur.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The full reference implementation code for the MO-NFT standard is included in the EIPs repository under assets folder. This ensures the code is preserved alongside the EIP and remains accessible.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Contracts&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7743&#x2F;.&#x2F;assets&#x2F;MONFT.sol&quot;&gt;&lt;code&gt;MONFT.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: The base implementation of the MO-NFT standard.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7743&#x2F;.&#x2F;assets&#x2F;DigitalAsset.sol&quot;&gt;&lt;code&gt;DigitalAsset.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: An extended implementation for digital assets with provider fees.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interfaces&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7743&#x2F;.&#x2F;assets&#x2F;IDigitalAsset.sol&quot;&gt;&lt;code&gt;IDigitalAsset.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: Interface defining the functions for digital asset management.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;key-functions-in-reference-implementation&quot;&gt;Key Functions in Reference Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Minting Tokens&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mintToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;    _nextTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add the sender to the set of owners for the new token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _owners&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_nextTokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increment the balance of the owner&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;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Set the provider to the caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _providers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_nextTokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenMinted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_nextTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; _nextTokenId&lt;&#x2F;span&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;&lt;strong&gt;Transferring Tokens&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MO-NFT: Caller is not an owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MO-NFT: Transfer to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MO-NFT: Recipient is already an owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add the new owner to the set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _owners&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&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&gt;    _balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer the transferValue to the provider&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; transferValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _transferValues&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; provider &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _providers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; transferValue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Insufficient contract balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; transferValue&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Transfer to provider failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenTransferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Archiving Ownership&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; archive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;            isOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;MO-NFT: Caller is not the owner of this token&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Once archived, the status cannot be reversed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            _archivedStatus&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-string&quot;&gt;            &amp;quot;MO-NFT: Token can only be archived once for an owner&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _archivedStatus&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ArchivedStatusUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; archived&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reentrancy Attacks&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mitigation&lt;&#x2F;strong&gt;: Use the Checks-Effects-Interactions pattern when transferring Ether (e.g., transferring &lt;code&gt;transferValue&lt;&#x2F;code&gt; to the provider).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Recommendation&lt;&#x2F;strong&gt;: Consider using &lt;code&gt;ReentrancyGuard&lt;&#x2F;code&gt; from OpenZeppelin to prevent reentrant calls.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integer Overflow and Underflow&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mitigation&lt;&#x2F;strong&gt;: Solidity 0.8.x automatically checks for overflows and underflows, throwing exceptions when they occur.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access Control&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ensured By&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Only owners can call transfer functions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Only providers can set the &lt;code&gt;transferValue&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use of &lt;code&gt;require&lt;&#x2F;code&gt; statements to enforce access control.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Denial of Service (DoS)&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consideration&lt;&#x2F;strong&gt;: Functions that iterate over owners could be expensive in terms of gas if the owners list is large.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mitigation&lt;&#x2F;strong&gt;: Avoid such functions or limit the number of owners.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Integrity&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ensured By&lt;&#x2F;strong&gt;: Proper use of Solidity&#x27;s data types and structures, and by emitting events for all state-changing operations for off-chain verification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ether Handling&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consideration&lt;&#x2F;strong&gt;: Ensure the contract can receive Ether to handle provider payments.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mitigation&lt;&#x2F;strong&gt;: Implement a &lt;code&gt;receive()&lt;&#x2F;code&gt; function to accept Ether.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Decentralized Identity Verification (DID)</title>
        <published>2024-06-26T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Anushka Yadav</name><uri>https://github.com/64anushka</uri><email>64anushka@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7734/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/discussion-on-decentralized-identity-verification-did-standard/20392" />
        

        <id>https://wg-eips.ritovision.com/7734/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7734"
            label="ERC-7734" />
        

        
        

        
        <summary type="html">A privacy-preserving method for decentralized identity verification, enabling secure integration of identity management in dApps.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7734/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces a standard for decentralized identity verification (DID) on the blockchain. The standard leverages cryptographic hashes to represent identity proofs and events for transparency and traceability. By emphasizing simplicity, privacy, and user control, this proposal aims to reduce overhead for developers and users, ensuring seamless integration into decentralized applications (dApps). It offers a minimalistic solution that keeps identity structure simple and enables off-chain mechanisms for detailed identity management and verification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Centralized identity verification methods are cumbersome, prone to data breaches, and fail to provide users control over their identity data. Existing DID solutions often introduce complexity, making adoption challenging for developers and users. This proposal seeks to address these issues by:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Offering a minimalistic, decentralized standard that simplifies identity verification.&lt;&#x2F;li&gt;
&lt;li&gt;Providing privacy-preserving mechanisms that keep sensitive identity data off-chain.&lt;&#x2F;li&gt;
&lt;li&gt;Encouraging wider adoption by enabling seamless integration into dApps across various industries.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;stakeholders&quot;&gt;Stakeholders&lt;&#x2F;h3&gt;
&lt;p&gt;The following stakeholders will benefit from this proposal:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;dapp-developers&quot;&gt;dApp Developers&lt;&#x2F;h4&gt;
&lt;p&gt;Developers creating decentralized applications that require identity verification can implement this standard to provide users with secure, decentralized identity management. The minimalistic design makes it easier to integrate into existing workflows without adding unnecessary complexity.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;service-providers&quot;&gt;Service Providers&lt;&#x2F;h4&gt;
&lt;p&gt;Platforms offering services such as decentralized finance (DeFi), gaming, or social networking can integrate this standard to verify user identities without relying on centralized authorities. This reduces the risk of fraud and enhances user trust.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;enterprises&quot;&gt;Enterprises&lt;&#x2F;h4&gt;
&lt;p&gt;Companies looking to integrate blockchain-based identity solutions into their existing systems can use this standard to ensure secure and privacy-preserving identity verification. This allows for a seamless transition to decentralized technologies while maintaining user privacy and security.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;developers-of-interoperability-solutions&quot;&gt;Developers of Interoperability Solutions&lt;&#x2F;h4&gt;
&lt;p&gt;Those working on cross-platform and cross-blockchain interoperability can implement this standard to enable a unified identity verification mechanism across different systems, reducing complexity and increasing user control over their identities.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;differentiation&quot;&gt;Differentiation&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal stands out from other DID standards by focusing on minimalism, user control, and privacy. Unlike other solutions that encompass a wide range of identity attributes and interactions, this standard keeps the structure simple and relies on off-chain mechanisms for detailed identity management. Its simplicity fosters easier adoption, making it ideal for dApps that prioritize user-centric, secure ecosystems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The Decentralized Identity Verification (DID) standard introduces a simple, secure, and privacy-preserving mechanism for verifying user identities on the  blockchain. The key components of this standard are outlined below:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;identity-contract&quot;&gt;Identity Contract&lt;&#x2F;h4&gt;
&lt;p&gt;A smart contract that acts as the central authority for identity verification. The contract stores the status of identity verifications for users and ensures that verification events are triggered securely and transparently.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;verification-function&quot;&gt;Verification Function&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;verifyIdentity&lt;&#x2F;code&gt; function allows a user to submit two verification hashes that represent off-chain proofs or attestations of identity. These hashes can be derived from external sources such as third-party verifiers, documents, or attestations.The function compares the provided hashes and updates the identity verification status accordingly.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;input-parameters&quot;&gt;Input Parameters:&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;strong&gt;identityHash:&lt;&#x2F;strong&gt; A cryptographic hash representing the user&#x27;s identity.
&lt;strong&gt;verificationHash:&lt;&#x2F;strong&gt; A cryptographic hash derived from the proof or attestation used to verify the identity.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;identityverified-event&quot;&gt;IdentityVerified Event&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;IdentityVerified&lt;&#x2F;code&gt; event is emitted when the user&#x27;s identity verification is successfully updated. This event ensures traceability and transparency, allowing dApp developers and users to track verification statuses.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;identity-structure&quot;&gt;Identity Structure&lt;&#x2F;h4&gt;
&lt;p&gt;The identity is a simple structure represented by a unique address (public key). Additional identity attributes, such as name or age, are optional and left to off-chain management. This minimal approach keeps the implementation lean, avoiding unnecessary complexity and encouraging broader adoption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDecentralizedIdentity&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Struct to represent an identity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Identity&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ethereum address of the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hash of the identity data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hashes used for verifying identity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; isVerified&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates if the identity is verified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; timestamp&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Timestamp of identity creation&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when a new identity is created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityCreated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when an identity is verified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityVerified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when an identity is revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to create a new decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identityHash: Hash of the identity data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to verify the decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - verificationHashes: Hashes used for verifying the identity. These can be &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   derived from off-chain proofs, cryptographic challenges, or other methods &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   specific to the implementer&amp;#39;s requirements. The exact meaning and derivation &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   of the verificationHashes are left to the contract&amp;#39;s implementer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to revoke the decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to retrieve the decentralized identity for a given user address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - userAddress Ethereum address of the user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identity The decentralized identity struct.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Identity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The design leverages cryptographic hashes to represent identity information, ensuring that sensitive data is not stored directly on the blockchain. The use of &lt;code&gt;verificationHashes&lt;&#x2F;code&gt; allows for flexible identity verification mechanisms. These hashes could be derived from various off-chain proofs, such as cryptographic challenges or attestations, depending on the implementer&#x27;s needs. By leaving the interpretation of the verification hashes open, the standard enables adaptability while maintaining privacy and security. Additionally, the inclusion of events ensures transparency and traceability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IDecentralizedIdentity.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DecentralizedIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDecentralizedIdentity&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mapping to store identities by user address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Identity&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; identities&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to create a new decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identityHash Hash of the identity data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure identity does not already exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;userAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Identity already exists&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create the identity for the caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Identity&lt;&#x2F;span&gt;&lt;span&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&gt;            userAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&gt;            identityHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            verificationHashes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initialize with empty hashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            isVerified&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emit event for the creation of a new identity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityCreated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; identityHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to verify the decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - verificationHashes: Hashes used for verifying the identity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure identity exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;userAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Identity does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Update verification hashes and mark identity as verified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;verificationHashes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isVerified &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emit event for the verification of identity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityVerified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; verificationHashes&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to revoke the decentralized identity for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure identity exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;userAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Identity does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mark identity as not verified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isVerified &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emit event for the revocation of identity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to retrieve the decentralized identity for a given user address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - userAddress Ethereum address of the user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identity The decentralized identity struct.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Identity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; identities&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;userAddress&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Secure Hashing&lt;&#x2F;strong&gt;: Ensure that identity and verification hashes are generated using a secure hashing algorithm to prevent collisions and ensure the integrity of the identity data.
&lt;strong&gt;Replay Attacks&lt;&#x2F;strong&gt;: Verification hashes should incorporate nonces or timestamps to prevent replay attacks.
&lt;strong&gt;Implementation Flexibility&lt;&#x2F;strong&gt;: Developers must ensure that hash generation and validation processes are robust and resistant to manipulation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Set Code for EOAs</title>
        <published>2024-05-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Sam Wilson</name><uri>https://github.com/SamWilsn</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7702/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923" />
        

        <id>https://wg-eips.ritovision.com/7702/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:7702"
            label="EIP-7702" />
        

        
        

        
        <summary type="html">Add a new tx type that permanently sets the code for an EOA</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7702/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add a new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction type that allows Externally
Owned Accounts (EOAs) to set the code in their account. This is done by
attaching a list of authorization tuples -- individually formatted as &lt;code&gt;[chain_id, address, nonce, y_parity, r, s]&lt;&#x2F;code&gt; -- to the transaction. For each tuple, a
delegation indicator &lt;code&gt;(0xef0100 || address)&lt;&#x2F;code&gt; is written to the authorizing
account&#x27;s code. All code executing operations must load and execute the code
pointed to by the delegation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Despite great advances in the smart contract wallet ecosystem, EOAs have held
back broad adoption of UX improvements across applications. This EIP therefore
focuses on adding short-term functionality improvements to EOAs which will allow
UX improvements to permeate through the entire application stack. Three
particular features this EIP is designed around are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Batching&lt;&#x2F;strong&gt;: allowing multiple operations from the same user in one atomic
transaction. One common example is an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; approval followed by
spending that approval. This is a common workflow in DEXes that requires two
transactions today. Advanced use cases of batching occasionally involve
dependencies: the output of the first operation is part of the input to the
second operation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Sponsorship&lt;&#x2F;strong&gt;: account X pays for a transaction on behalf of account Y.
Account X could be paid in some other ERC-20 for this service, or it could be an
application operator including the transactions of its users for free.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Privilege de-escalation&lt;&#x2F;strong&gt;: users can sign sub-keys and give them specific
permissions that are much weaker than global access to the account. For example,
a permission to spend ERC-20 tokens but not ETH, or to spend up to 1% of the
total balance per day, or to interact only with a specific application.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SET_CODE_TX_TYPE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x04&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAGIC&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x05&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;PER_AUTH_BASE_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;12500&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;PER_EMPTY_ACCOUNT_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;25000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;set-code-transaction&quot;&gt;Set code transaction&lt;&#x2F;h3&gt;
&lt;p&gt;A new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction known as the &quot;set code transaction&quot;
is introduced, where the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; is &lt;code&gt;SET_CODE_TX_TYPE&lt;&#x2F;code&gt; and the
&lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; is the RLP serialization of the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;destination, value, data, access_list, authorization_list, signature_y_parity,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;signature_r, signature_s])&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;authorization_list = [[chain_id, address, nonce, y_parity, r, s], ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The fields &lt;code&gt;chain_id&lt;&#x2F;code&gt;, &lt;code&gt;nonce&lt;&#x2F;code&gt;, &lt;code&gt;max_priority_fee_per_gas&lt;&#x2F;code&gt;, &lt;code&gt;max_fee_per_gas&lt;&#x2F;code&gt;,
&lt;code&gt;gas_limit&lt;&#x2F;code&gt;, &lt;code&gt;destination&lt;&#x2F;code&gt;, &lt;code&gt;value&lt;&#x2F;code&gt;, &lt;code&gt;data&lt;&#x2F;code&gt;, and &lt;code&gt;access_list&lt;&#x2F;code&gt; of the outer
transaction follow the same semantics as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;. &lt;em&gt;Note, this
implies a null destination is not valid.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;signature_y_parity, signature_r, signature_s&lt;&#x2F;code&gt; elements of this transaction
represent a secp256k1 signature over &lt;code&gt;keccak256(SET_CODE_TX_TYPE || TransactionPayload)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;authorization_list&lt;&#x2F;code&gt; is a list of tuples that indicate what code the signer
of each tuple desires to execute in the context of their EOA. The transaction is
considered invalid if the length of &lt;code&gt;authorization_list&lt;&#x2F;code&gt; is zero.&lt;&#x2F;p&gt;
&lt;p&gt;The transaction is also considered invalid when any field in an authorization
tuple cannot fit within the following bounds:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chain_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;y_parity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; for this transaction is
&lt;code&gt;rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;behavior&quot;&gt;Behavior&lt;&#x2F;h4&gt;
&lt;p&gt;The authorization list is processed before the execution portion of the
transaction begins, but after the sender&#x27;s nonce is incremented.&lt;&#x2F;p&gt;
&lt;p&gt;For each &lt;code&gt;[chain_id, address, nonce, y_parity, r, s]&lt;&#x2F;code&gt; tuple, perform the
following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Verify the chain ID is 0 or the ID of the current chain.&lt;&#x2F;li&gt;
&lt;li&gt;Verify the &lt;code&gt;nonce&lt;&#x2F;code&gt; is less than &lt;code&gt;2**64 - 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Let &lt;code&gt;authority = ecrecover(msg, y_parity, r, s)&lt;&#x2F;code&gt;.
&lt;ul&gt;
&lt;li&gt;Where &lt;code&gt;msg = keccak(MAGIC || rlp([chain_id, address, nonce]))&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Verify &lt;code&gt;s&lt;&#x2F;code&gt; is less than or equal to &lt;code&gt;secp256k1n&#x2F;2&lt;&#x2F;code&gt;, as specified in
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2&#x2F;&quot;&gt;EIP-2&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;authority&lt;&#x2F;code&gt; to &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;, as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Verify the code of &lt;code&gt;authority&lt;&#x2F;code&gt; is empty or already delegated.&lt;&#x2F;li&gt;
&lt;li&gt;Verify the nonce of &lt;code&gt;authority&lt;&#x2F;code&gt; is equal to &lt;code&gt;nonce&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST&lt;&#x2F;code&gt; gas to the global refund
counter if &lt;code&gt;authority&lt;&#x2F;code&gt; is not empty.&lt;&#x2F;li&gt;
&lt;li&gt;Set the code of &lt;code&gt;authority&lt;&#x2F;code&gt; to be &lt;code&gt;0xef0100 || address&lt;&#x2F;code&gt;. This is a delegation
indicator.
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;address&lt;&#x2F;code&gt; is &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;, do not write
the delegation indicator. Clear the account&#x27;s code by resetting the account&#x27;s
code hash to the empty code hash
&lt;code&gt;0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Increase the nonce of &lt;code&gt;authority&lt;&#x2F;code&gt; by one.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If any step above fails, immediately stop processing the tuple and continue to
the next tuple in the list. When multiple tuples from the same authority are
present, set the code using the address in the last valid occurrence.&lt;&#x2F;p&gt;
&lt;p&gt;Note, if transaction execution results in failure (e.g. any exceptional
condition or code reverting), the processed delegation indicators is &lt;em&gt;not rolled
back&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;delegation-indicator&quot;&gt;Delegation indicator&lt;&#x2F;h5&gt;
&lt;p&gt;Delegation indicators use the banned opcode &lt;code&gt;0xef&lt;&#x2F;code&gt;, defined in
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3541&#x2F;&quot;&gt;EIP-3541&lt;&#x2F;a&gt;, to indicate that the code must be handled differently
than regular code. The delegation forces all code executing operations to follow
the address pointer to obtain the code to execute. For example, &lt;code&gt;CALL&lt;&#x2F;code&gt; loads the
code at &lt;code&gt;address&lt;&#x2F;code&gt; and executes it in the context of &lt;code&gt;authority&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The affected executing operations are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CALL&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CALLCODE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;STATICCALL&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;any transaction where &lt;code&gt;destination&lt;&#x2F;code&gt; points to an address with a delegation
indicator present&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For code reading, only &lt;code&gt;CODESIZE&lt;&#x2F;code&gt; and &lt;code&gt;CODECOPY&lt;&#x2F;code&gt; instructions are affected. They
operate directly on the executing code instead of the delegation. For example,
when executing a delegated account &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; returns &lt;code&gt;23&lt;&#x2F;code&gt; (the size of
&lt;code&gt;0xef0100 || address&lt;&#x2F;code&gt;) whereas &lt;code&gt;CODESIZE&lt;&#x2F;code&gt; returns the size of the code residing
at &lt;code&gt;address&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note, this means during delegated execution &lt;code&gt;CODESIZE&lt;&#x2F;code&gt; and &lt;code&gt;CODECOPY&lt;&#x2F;code&gt; produce a
different result compared to calling &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; and &lt;code&gt;EXTCODECOPY&lt;&#x2F;code&gt; on the
authority.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h6 id=&quot;precompiles&quot;&gt;Precompiles&lt;&#x2F;h6&gt;
&lt;p&gt;When a precompile address is the target of a delegation, the retrieved code is
considered empty and &lt;code&gt;CALL&lt;&#x2F;code&gt;, &lt;code&gt;CALLCODE&lt;&#x2F;code&gt;, &lt;code&gt;STATICCALL&lt;&#x2F;code&gt;, &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt;
instructions targeting this account will execute empty code, and therefore
succeed with no execution when given enough gas to initiate the call.&lt;&#x2F;p&gt;
&lt;h6 id=&quot;loops&quot;&gt;Loops&lt;&#x2F;h6&gt;
&lt;p&gt;In case a delegation indicator points to another delegation, creating a
potential chain or loop of delegations, clients must retrieve only the first
code and then stop following the delegation chain.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;gas-costs&quot;&gt;Gas Costs&lt;&#x2F;h4&gt;
&lt;p&gt;The intrinsic cost of the new transaction is inherited from
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2930&#x2F;&quot;&gt;EIP-2930&lt;&#x2F;a&gt;, specifically &lt;code&gt;21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * access list storage key count + 2400 * access list address count&lt;&#x2F;code&gt;. Additionally, add a cost of &lt;code&gt;PER_EMPTY_ACCOUNT_COST * authorization list length&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The transaction sender will pay for all authorization tuples, regardless of
validity or duplication.&lt;&#x2F;p&gt;
&lt;p&gt;If a code executing instruction accesses a cold account during the resolution of
delegated code, add an additional &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt;
&lt;code&gt;COLD_ACCOUNT_READ_COST&lt;&#x2F;code&gt; cost of &lt;code&gt;2600&lt;&#x2F;code&gt; gas to the normal cost and add the
account to &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;. Otherwise, assess a &lt;code&gt;WARM_STORAGE_READ_COST&lt;&#x2F;code&gt;
cost of &lt;code&gt;100&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;transaction-origination&quot;&gt;Transaction origination&lt;&#x2F;h4&gt;
&lt;p&gt;Modify the restriction put in place by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3607&#x2F;&quot;&gt;EIP-3607&lt;&#x2F;a&gt; to allow EOAs
whose code is a valid delegation indicator, i.e. &lt;code&gt;0xef0100 || address&lt;&#x2F;code&gt;, to
originate transactions. Accounts with any other code values may not originate
transactions.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, if a transaction&#x27;s &lt;code&gt;destination&lt;&#x2F;code&gt; has a delegation indicator, add
the target of the delegation to &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Below is the rationale for both general design directions of the EIP, as well as
specific technical choices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;general-design-philosophy&quot;&gt;General design philosophy&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;persistence-of-code-delegation&quot;&gt;Persistence of code delegation&lt;&#x2F;h4&gt;
&lt;p&gt;The first draft of this proposal had a clever idea to avoid disagreement on
whether in-protocol revocation was needed or not. The idea was to temporarily
set code in the account with the authorization. After the transaction finished,
the code would be completely cleared. This was a new design space for enriching
EOA functionality.&lt;&#x2F;p&gt;
&lt;p&gt;Even this approach was not without its flaws. Fundamentally, there was not much
friction for users including set code authorizations. This meant that some users
and applications would opt to treat the extension as more of a scripting
facility, rather than a full-fledged upgrade to a smart contract wallet. The
outcome of this would be two somewhat competing workstreams for UX improvements:
smart contract wallets and EOA scripts.&lt;&#x2F;p&gt;
&lt;p&gt;Previous proposals had been met with similar criticisms. To counteract this,
persistent delegations were introduced. They create enough friction in
deployment that users will not deploy new, unique ones regularly. This will
hopefully unify the workstreams and minimize fragmentation in UX developments.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;no-initcode&quot;&gt;No initcode&lt;&#x2F;h4&gt;
&lt;p&gt;Running initcode is not desirable for many reasons. It creates a new mode of
execution that needs extensive testing, and may be used for purposes not
possible with standard smart contract wallets. It also forces developers to
perform initialization as a standard call to the EOA after delegation. The lack
of atomicity in these operations is another factor that will push users to
complete smart contract wallet solutions, instead of EOA scripts.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, initcode tends to be propagated inside the transaction calldata.
This means it would need to be included in the authorization tuple and signed
over. The minimum initcode is around 15 bytes -- it would simply copy the
contract code from an external address. The total cost would be &lt;code&gt;16 * 15 = 240&lt;&#x2F;code&gt;
calldata cost, plus the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3860&#x2F;&quot;&gt;EIP-3860&lt;&#x2F;a&gt; cost of &lt;code&gt;2 * 15 = 30&lt;&#x2F;code&gt;, plus
the runtime costs of around &lt;code&gt;150&lt;&#x2F;code&gt;. So nearly &lt;code&gt;500&lt;&#x2F;code&gt; additional gas would be spent
preparing the account. Even more likely, 1200+ gas if not copying from an
external account.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;creation-by-template&quot;&gt;Creation by template&lt;&#x2F;h4&gt;
&lt;p&gt;Initcode or not, there is a question of how users should specify the code they
intend to run in their account. The two main options are to specify the bytecode
directly in the transaction or to specify a pointer to the code. The simplest
pointer would just be the address of code deployed on-chain.&lt;&#x2F;p&gt;
&lt;p&gt;The cost analysis makes the answer clear. The smallest proxy would be around 50
bytes and an address is 20 bytes. The 30 byte difference provides no useful
additional functionality and will be inefficiently replicated billions of times.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, specifying code directly would again make it possible for EOAs to
have a new, unique ability to execute arbitrary code specified in the
transaction calldata. It is for these reasons that creation by template is
chosen.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;interaction-with-applications-and-wallets&quot;&gt;Interaction with applications and wallets&lt;&#x2F;h4&gt;
&lt;p&gt;While this EIP provides a lot of flexibility to applications and EOAs, there are
incorrect ways of using it. Applications &lt;strong&gt;must not&lt;&#x2F;strong&gt; expect that they can
suggest the user sign an authorization, and therefore it is the duty of the
wallet to not provide an interface to do so.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;There is no safe way to provide this interface&lt;&#x2F;strong&gt;. The code specified by an
authorization has unrestricted access to the account and must always be closely
audited by the wallet. Few users have the level of sophistication to reasonably
verify the code they are delegating to.&lt;&#x2F;p&gt;
&lt;p&gt;It is also not possible to implement a system of permissions at this level to
minimize the risk. If applications require custom wallet functionality, they
must use standardized extension &#x2F; module systems built on top of the delegated
code that correctly implements permissions.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;forward-compatibility-with-future-account-abstraction&quot;&gt;Forward-compatibility with future account abstraction&lt;&#x2F;h4&gt;
&lt;p&gt;This EIP is designed to be forward-compatible with endgame account abstraction,
without over-enshrining any fine-grained details of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; or
RIP-7560.&lt;&#x2F;p&gt;
&lt;p&gt;To start, the &lt;code&gt;address&lt;&#x2F;code&gt; that users sign could directly point to existing
ERC-4337 wallet code. This essentially requires the &quot;code pathways&quot; that are
used are code pathways that would, in most cases, continue to make sense in a
pure-smart-contract-wallet world. Hence, it avoids the problem of creating two
separate UX workstreams because, to a large extent, they would be the same
ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;There will be some workflows that require kludges under this solution that would
be better done in some different &quot;more native&quot; under &quot;endgame AA&quot;, but this is
relatively a small subset. The EIP does not require adding any opcodes, that
would become dangling and useless in a post-EOA world, and it allows EOAs to
masquerade as contracts to be included in ERC-4337 bundles, in a way that&#x27;s
compatible with the existing &lt;code&gt;EntryPoint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;self-sponsoring-allowing-tx-origin-to-set-code&quot;&gt;Self-sponsoring: allowing &lt;code&gt;tx.origin&lt;&#x2F;code&gt; to set code&lt;&#x2F;h4&gt;
&lt;p&gt;Allowing &lt;code&gt;tx.origin&lt;&#x2F;code&gt; to set code and execute its own delegated code enables what
is called self-sponsoring. It allows users to take advantage of EIP-7702 without
relying on any third party infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;However, that means the EIP breaks the invariant that &lt;code&gt;msg.sender == tx.origin&lt;&#x2F;code&gt;
only happens in the topmost execution frame of a transaction. This will affect
smart contracts containing &lt;code&gt;require(msg.sender == tx.origin)&lt;&#x2F;code&gt; style checks. This
check is used for at least three purposes:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Ensuring that &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is an EOA (given that &lt;code&gt;tx.origin&lt;&#x2F;code&gt; always has to be
an EOA). This invariant does not depend on the execution layer depth and,
therefore, is not affected.&lt;&#x2F;li&gt;
&lt;li&gt;Protecting against atomic sandwich attacks like flash loans, which rely on
the ability to modify state before and after the execution of the target
contract as part of the same atomic transaction. This protection would be broken
by this EIP. However, relying on &lt;code&gt;tx.origin&lt;&#x2F;code&gt; in this way is considered bad
practice, and can already be circumvented by miners conditionally including
transactions in a block.&lt;&#x2F;li&gt;
&lt;li&gt;Preventing reentrancy.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Examples of (1) and (2) can be found in contracts deployed on Ethereum mainnet,
with (1) being more common (and unaffected by this proposal). On the other hand,
use case (3) is more severely affected by this proposal, but the authors of this
EIP did not find any examples of this form of reentrancy protection, though the
search was non-exhaustive.&lt;&#x2F;p&gt;
&lt;p&gt;This distribution of occurrences—many (1), some (2), and no (3)—is exactly what
the authors of this EIP expect because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Determining if &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is an EOA without &lt;code&gt;tx.origin&lt;&#x2F;code&gt; is difficult, if not
impossible.&lt;&#x2F;li&gt;
&lt;li&gt;The only execution context which is safe from atomic sandwich attacks is the
topmost context, and &lt;code&gt;tx.origin == msg.sender&lt;&#x2F;code&gt; is the only way to detect that
context.&lt;&#x2F;li&gt;
&lt;li&gt;In contrast, there are many direct and flexible ways of preventing reentrancy
(e.g., using a transient storage variable). Since &lt;code&gt;msg.sender == tx.origin&lt;&#x2F;code&gt; is
only true in the topmost context, it would make an obscure tool for preventing
reentrancy, rather than other more common approaches.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are other approaches to mitigate this restriction which do not break the
invariant:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;tx.origin&lt;&#x2F;code&gt; to a constant &lt;code&gt;ENTRY_POINT&lt;&#x2F;code&gt; address when using the &lt;code&gt;CALL*&lt;&#x2F;code&gt;
instruction in the context of an EOA.&lt;&#x2F;li&gt;
&lt;li&gt;Set &lt;code&gt;tx.origin&lt;&#x2F;code&gt; to a special address derived from the sender or signer
addresses.&lt;&#x2F;li&gt;
&lt;li&gt;Disallow &lt;code&gt;tx.origin&lt;&#x2F;code&gt; from setting code. This would make the simple batching
use cases impossible, but could be relaxed in the future.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;rationale-for-technical-details&quot;&gt;Rationale for technical details&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;cost-of-delegation&quot;&gt;Cost of delegation&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;PER_AUTH_BASE_COST&lt;&#x2F;code&gt; is the cost to process the authorization tuple and set
the delegation destination. To compute a fair cost for this operation, the
authors review its impact on the system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ferry 101 bytes of calldata = &lt;code&gt;101 * non-zero cost (16) = 1616&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;recovering the &lt;code&gt;authority&lt;&#x2F;code&gt; address = &lt;code&gt;3000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reading the nonce and code of &lt;code&gt;authority&lt;&#x2F;code&gt; = &lt;code&gt;2600&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;storing values in already warm account = &lt;code&gt;200&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;cost to deploy code = &lt;code&gt;200 * 23 = 4600&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The impact-based assessment identifies &lt;code&gt;12016&lt;&#x2F;code&gt; gas of comparable computation for
the operation. It is rounded up to &lt;code&gt;12500&lt;&#x2F;code&gt; to account for miscellaneous costs
associated with shuttling data around the state transition.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;clearing-delegation-indicators&quot;&gt;Clearing delegation indicators&lt;&#x2F;h4&gt;
&lt;p&gt;A general design goal in state transition changes is to minimize the number of
special cases an EIP has. In early iterations, this EIP resisted a special case
for clearing an account&#x27;s delegation indicator.&lt;&#x2F;p&gt;
&lt;p&gt;For most intents and purposes, an account delegated to &lt;code&gt;0x0&lt;&#x2F;code&gt; is
indistinguishable from a true EOA. However, one particular unfortunate case is
unavoidable. Even if a user has a zeroed out delegation indicator, most
operations that interact with that account will incur an additional
&lt;code&gt;COLD_ACCOUNT_READ_COST&lt;&#x2F;code&gt; upon the first touch caused by attempting to load the
code at &lt;code&gt;0x0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For this reason, the authors have opted to include a special case which allow
users to restore their EOA to its original purity.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lack-of-instruction-prohibition&quot;&gt;Lack of instruction prohibition&lt;&#x2F;h4&gt;
&lt;p&gt;Consistency is a valuable property in the EVM, both from an implementation
perspective and a user-understanding-perspective. Despite considering bans on
several families of instructions in the context of EOAs, the authors feel there
is not a compelling reason to do so, as it would cause smart contract wallets
and EOA smart contract wallets to proceed down distinct UX workstreams.&lt;&#x2F;p&gt;
&lt;p&gt;The main instruction families where a ban was considered were storage related
and contract creation related. The decision to not ban storage instructions
hinged mostly on their importance to smart contract wallets. Although it&#x27;s
possible to have an external storage contract that the smart contract wallet
calls into, it is unnecessarily complicated and inefficient. In the future, new
state schemes may allow substantially cheaper access to certain storage slots
within an account. This is something smart contract wallets will want to take
advantage of that a storage contract wouldn&#x27;t support.&lt;&#x2F;p&gt;
&lt;p&gt;Creation instructions were considered for a ban as well on other similar EIPs,
however because this EIP allows EOAs to spend value intra-transaction, the
concern with bumping the nonce intra-transaction and invalidating pending
transactions is not significant.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;protection-from-malleability-cross-chain&quot;&gt;Protection from malleability cross-chain&lt;&#x2F;h4&gt;
&lt;p&gt;One consideration when signing a code pointer is what code that address points
to on another chain. While it is possible to create a deterministic deployment,
i.e. via Nick&#x27;s method, verifying such a deployment may not always be desirable.
In such situations, the chain ID can be set to reduce the scope of the
authorization. When universal deployment is preferred, simply set chain ID to 0.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative to adding chain ID could be to substitute in the actual code for
the address in the signature. This seems to have the benefit of both minimizing
the on-chain size of auth tuples, by continuing to serialize only the address,
while retaining specificity of the actual code running in the account, by
pulling in the code for the signature. One unfortunate issue of this format,
though, is that it imposes a database lookup to determine the signer of each
auth tuple. This imposition itself seems to create enough complexity in
transaction propagation that it is decided to avoid and simply sign over the
address directly.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;delegation-of-code-execution-only&quot;&gt;Delegation of code execution only&lt;&#x2F;h4&gt;
&lt;p&gt;Other code retrieving operations like &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; do not automatically follow
delegations, they operate on the delegation indicator itself. If instead
delegations were followed, an account would be able to temporarily masquerade as
having a particular codehash, which would break contracts that rely on
codehashes as a definition of possible account behavior. A change of behavior in
a contract is currently only possible if its code explicitly allows it (in
particular via &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt;), and a change of codehash is only possible in the
presence of &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; (which, as of Cancun, only applies in the same
transaction as contract creation), so choosing to follow delegations in
&lt;code&gt;EXTCODE*&lt;&#x2F;code&gt; opcodes would have created a new type of account breaking prior
assumptions.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;charge-maximum-cost-upfront&quot;&gt;Charge maximum cost upfront&lt;&#x2F;h4&gt;
&lt;p&gt;While computing the intrinsic gas cost, the transaction is charged the
worst-case cost for each delegation. Later, while processing the authorization
list, a refund is issued if the account already exists in state. This mechanism
is designed to avoid state lookups for each authorization when computing the
intrinsic gas and can quickly determine the validity of the transaction with
only a state lookup on the sender&#x27;s account.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;no-blobs-no-contract-creation&quot;&gt;No blobs, no contract creation&lt;&#x2F;h4&gt;
&lt;p&gt;Transactions should be thought of as specialized tools and not necessarily a
one-type-does-all solution. EIP-4844 is treated differently at the p2p level due
to burden blobs place on a node&#x27;s bandwidth. EIP-7702 has different implications
on transaction gossiping and there is no need to complicate those rules
unnecessarily by making it a superset of all possible functionality. The authors
ultimately do not expect there to be much demand for atomic delegation and blob
submission.&lt;&#x2F;p&gt;
&lt;p&gt;Contract creation is another specialized use case that has been grandfathered
into several transaction types. It adds complexity to testing, because it is a
new distinct branch of execution that needs to be tested when any change to the
EVM occurs and verify the change works as expected in that context.&lt;&#x2F;p&gt;
&lt;p&gt;For these reasons, the authors have chosen to keep the scope of the EIP focused
on improving UX.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;disallow-delegation-to-precompiles&quot;&gt;Disallow delegation to precompiles&lt;&#x2F;h4&gt;
&lt;p&gt;Precompiles are themselves edge cases, so allowing delegations to precompiles or
not requires some focus in implementation. Considering the fact that precompiles
technically do not have code associated with their accounts, the authors decided
it would be marginally simpler to not execute the precompile logic when a user
delegates to one. This is somewhat unintuitive.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;non-empty-authorization-list-required&quot;&gt;Non-empty authorization list required&lt;&#x2F;h4&gt;
&lt;p&gt;Set code transactions are required to have at least one authorization to be
considered valid. This is to disincentivize senders from using type 4
transactions as a generic transaction format, because this transaction has
different implications on the transaction pool than, say,
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt; transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP breaks a few invariants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An account balance can only decrease as a result of a transaction originating
from that account.
&lt;ul&gt;
&lt;li&gt;Once an account has been delegated, any call to the account may also cause
the balance to decrease.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;An EOA nonce may not increase after transaction execution has begun.
&lt;ul&gt;
&lt;li&gt;Once an account has been delegated, the account may call a create operation
during execution, causing the nonce to increase.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tx.origin == msg.sender&lt;&#x2F;code&gt; can only be true in the topmost frame of execution.
&lt;ul&gt;
&lt;li&gt;Once an account has been delegated, it can invoke multiple calls per
transaction.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;implementation-of-secure-delegate-contracts&quot;&gt;Implementation of secure delegate contracts&lt;&#x2F;h3&gt;
&lt;p&gt;The following is a non-exhaustive list of pitfalls that delegate contracts
&lt;em&gt;should&lt;&#x2F;em&gt; be wary of and require a signature over from the account&#x27;s authority:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Replay protection (e.g., a nonce) should be implemented by the delegate and
signed over. Without it, a malicious actor can reuse a signature, repeating its
effects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;value&lt;&#x2F;code&gt; -- without it, a malicious sponsor could cause unexpected effects in
the callee.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gas&lt;&#x2F;code&gt; -- without it, a malicious sponsor could cause the callee to run out of
gas and fail, griefing the sponsee.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;target&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;calldata&lt;&#x2F;code&gt; -- without them, a malicious actor may call arbitrary
functions in arbitrary contracts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A poorly implemented delegate can &lt;em&gt;allow a malicious actor to take near complete
control over a signer&#x27;s EOA&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;front-running-initialization&quot;&gt;Front running initialization&lt;&#x2F;h3&gt;
&lt;p&gt;Smart contract wallet developers must consider the implications of setting code
in an account without execution. Contracts are normally deployed by executing
initcode to determine the exact code to be placed in the account. This gives
developers the opportunity to initialize storage slots at the same time. The
initial values of the account cannot be replaced by an observer, because they
are either signed over by an EOA in the case of a creation transaction or they
are committed to by computing the contract&#x27;s address deterministically from the
hash of the initcode.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not provide developers the opportunity to run initcode and set
storage slots during delegation. To secure the account from an observer
front-running the initialization of the delegation with an account they control,
smart contract wallet developers must verify the initial calldata to the account
for setup purposes be signed by the EOA&#x27;s key using ecrecover. This ensures the
account can only be initialized with desirable values.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;storage-management&quot;&gt;Storage management&lt;&#x2F;h3&gt;
&lt;p&gt;Changing an account&#x27;s delegation is a security-critical operation that should
not be done lightly, especially if the newly delegated code is not purposely
designed and tested as an upgrade to the old one.&lt;&#x2F;p&gt;
&lt;p&gt;In particular, in order to ensure a safe migration of an account from one
delegate contract to another, it&#x27;s important for these contracts to use storage
in a way that avoids accidental collisions among them. For example, using
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7201&#x2F;&quot;&gt;ERC-7201&lt;&#x2F;a&gt; a contract may root its storage layout at a slot
dependent on a unique identifier. To simplify this, smart contract languages may
provide a way of re-rooting the entire storage layout of existing contract
source code.&lt;&#x2F;p&gt;
&lt;p&gt;If all contracts previously delegated to by the account used the approach
described above, a migration should not cause any issues. However, if there is
any doubt, it is recommended to first clear all account storage, an operation
that is not natively offered by the protocol but that a special-purpose delegate
contract can be designed to implement.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-code-as-tx-origin&quot;&gt;Setting code as &lt;code&gt;tx.origin&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Allowing the sender of an EIP-7702 to also set code has the possibility to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Break atomic sandwich protections which rely on &lt;code&gt;tx.origin&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;Break reentrancy guards of the style &lt;code&gt;require(tx.origin == msg.sender)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The authors of this EIP believe the risks of allowing this are acceptable for
the reasons outlined in the Rationale section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sponsored-transaction-relayers&quot;&gt;Sponsored transaction relayers&lt;&#x2F;h3&gt;
&lt;p&gt;It is possible for the &lt;code&gt;authorized&lt;&#x2F;code&gt; account to cause sponsored transaction
relayers to spend gas without being reimbursed by either invalidating the
authorization (i.e., increasing the account&#x27;s nonce) or by sweeping the relevant
assets out of the account. Relayers should be designed with these cases in mind,
possibly by requiring a bond to be deposited or by implementing a reputation
system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transaction-propagation&quot;&gt;Transaction propagation&lt;&#x2F;h3&gt;
&lt;p&gt;Allowing EOAs to behave as smart contracts via the delegation indicator poses
some challenges for transaction propagation. Traditionally, EOAs have only been
able to send value via a transaction. This invariant allows nodes to statically
determine the validity of transactions for that account. In other words, a
single transaction has only been able to invalidate transactions pending from
the sender&#x27;s account.&lt;&#x2F;p&gt;
&lt;p&gt;With this EIP, it becomes possible to cause transactions from other accounts to
become stale. This is due to the fact that once an EOA has delegated to code,
that code can be called by anyone at any point in a transaction. It becomes
impossible to know if the balance of the account has been swept in a static
manner.&lt;&#x2F;p&gt;
&lt;p&gt;While there are a few mitigations for this, the authors recommend that clients
do not accept more than one pending transaction for any EOA with a non-zero
delegation indicator. This minimizes the number of transactions that can be
invalidated by a single transaction.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative would be to expand the EIP-7702 transaction with a list of
accounts the caller wishes to &quot;hydrate&quot; during the transaction. Those accounts
behave as the delegated code &lt;em&gt;only&lt;&#x2F;em&gt; for EIP-7702 transactions which include them
in such a list, thus returning to clients the ability to statically analyze and
reason about pending transactions.&lt;&#x2F;p&gt;
&lt;p&gt;A related issue is that an EOA&#x27;s nonce may be incremented more than once per
transaction. Because clients already need to be robust in a worse scenario
(described above), it isn&#x27;t a major concern. However, clients should be aware
this behavior is possible and design their transaction propagation accordingly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blob throughput increase</title>
        <published>2024-04-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Parithosh Jayanthi</name><uri>https://github.com/parithosh</uri>
	</author>
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	<author>
		<name>Sam Calder-Mason</name><uri>https://github.com/samcm</uri>
	</author>
	
	<author>
		<name>Andrew Davis</name><uri>https://github.com/savid</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7691/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7691-blob-throughput-increase/19694" />
        

        <id>https://wg-eips.ritovision.com/7691/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7691"
            label="EIP-7691" />
        

        
        

        
        <summary type="html">Increase the number of blobs to reach a new target and max of 6 and 9 blobs per block respectively</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7691/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Increases the number of blobs in a block to provide more scale to Ethereum via L2 solution that rely on L1 data capacity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum, with its rollup centric roadmap, scales by relying on L2. Since the Dencun fork, the blob gas target and maximum was set to 3&#x2F;6 respectively. The blob gas limit was arrived at based on a series of big block tests performed on the Ethereum mainnet network as well as a series of testnets. The values were chosen cautiously, as it&#x27;s extremely hard to predict the exact p2p behaviour of Ethereum mainnet.&lt;&#x2F;p&gt;
&lt;p&gt;As we now have the Dencun upgrade live, we are able to use monitoring tools to check the network health. Initial monitoring indicates that we have a stable network with the current gas target and the re-org rate is trending downwards. Additionally, analysis on messages in gossipsub indicate that the inclusion of &lt;code&gt;IDONTWANT&lt;&#x2F;code&gt; messages could bring us a significant bandwidth savings. This allows us to consider starting a series of big block and blob tests to determine the theoretical headroom we currently have. The EIP specifies a proposed new blob gas target and limit based on the series of tests.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP aims to increase the throughput short term to provide some scaling until future solutions are deployed. In order to alleviate valid concerns about solo-stakers, approaches such as the inclusion of a flag indicating the max blobs per block for locally built blocks could be considered.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;9&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1179648&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;786432&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;5007716&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;MAX_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt; and &lt;code&gt;TARGET_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt; are consumed by the consensus layer clients, and starting at &lt;code&gt;PECTRA_FORK_EPOCH&lt;&#x2F;code&gt; replace the respective old max and target values.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;, &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE&lt;&#x2F;code&gt; are consumed by the execution layer clients, and starting at the epoch when this EIP is activated, replace the old max, target and update fraction values.
Any references to &lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; should be updated to the new values defined in this EIP when processing the activation block.
The value &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE&lt;&#x2F;code&gt; replaces its previous equivalent when processing the activation block.
These changes imply that &lt;code&gt;get_base_fee_per_blob_gas&lt;&#x2F;code&gt; and &lt;code&gt;calc_excess_blob_gas&lt;&#x2F;code&gt; functions defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; use the new values for the first block of the fork (and for all subsequent blocks).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;simplicity&quot;&gt;Simplicity&lt;&#x2F;h3&gt;
&lt;p&gt;The EIP aims to minimize the amount of testing and implementation effort from the perspective of the client teams, to allow for more resources to be allocated to peerDAS and other scaling research.&lt;&#x2F;p&gt;
&lt;p&gt;While this EIP may not achieve the new optimal blob limit, it offers a compromise for a short term increase.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;update-fraction&quot;&gt;Update Fraction&lt;&#x2F;h3&gt;
&lt;p&gt;The original target and max values from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; were at a 1:2 ratio. As a consequence, responsiveness to full and empty blob sections was symmetrical:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;full blobs: basefee increases by ~12.5%&lt;&#x2F;li&gt;
&lt;li&gt;no blobs: basefee decreases by ~11.1%&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The new target and max values from this EIP are at a 2:3 ratio, which breaks that symmetry. As a consequence, the basefee becomes significantly more responsive to empty blob sections (that are 6 blobs under target) than to full ones (that are 3 blobs over target). This is by design, as it takes two blocks with full blobs in a row to make up for a single block with no blobs. However, it creates the challenge of finding a good compromise base fee sensitivity level.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE&lt;&#x2F;code&gt; value in this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no blobs constant:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;full blobs: basefee increases by ~8.2%&lt;&#x2F;li&gt;
&lt;li&gt;no blobs: basefee decreases by ~14.5%&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The consensus clients would continue to use &lt;code&gt;MAX_BLOBS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;TARGET_BLOBS_PER_BLOCK&lt;&#x2F;code&gt; for the deneb fork and once the &lt;code&gt;ELECTRA&lt;&#x2F;code&gt; fork is active, they would use &lt;code&gt;MAX_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt; and &lt;code&gt;TARGET_BLOBS_PER_BLOCK_ELECTRA&lt;&#x2F;code&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;The execution clients would continue to use &lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;, &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt; for the cancun fork and once the prague fork is active, they would use &lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;, &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE&lt;&#x2F;code&gt; respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;network-impacts&quot;&gt;Network Impacts&lt;&#x2F;h3&gt;
&lt;p&gt;Through the use of big block&#x2F;blob tests on Ethereum mainnet as well as testnets, we can earn a high degree of certainty that the blob limit increase would not negatively impact the network. These tests as well as the associated analysis can be performed mostly by non-client team entities, with minimal input required. Since the changes are quite contained, the EIP should be able to reduce the risk of the blob limit increase.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;stability-around-fork-epoch&quot;&gt;Stability Around Fork Epoch&lt;&#x2F;h3&gt;
&lt;p&gt;A blob limit increase at the fork transition is relatively straightforward from an implementation perspective. We would need to deploy an increased amount of monitoring around the fork epoch, but after a period of stability we can assume that the blob limit increase was successful, reducing any unexpected co-ordination efforts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>General purpose execution layer requests</title>
        <published>2024-04-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	<author>
		<name>Felix Lange</name><uri>https://github.com/fjl</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7685/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7685-general-purpose-execution-layer-requests/19668" />
        

        <id>https://wg-eips.ritovision.com/7685/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7685"
            label="EIP-7685" />
        

        
        

        
        <summary type="html">A general purpose bus for sharing EL triggered requests with the CL</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7685/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal defines a general purpose framework for storing contract-triggered
requests. It extends the execution header with a single field to store the
request information. Requests are later on exposed to the consensus layer, which
then processes each one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The proliferation of smart contract controlled validators has caused there to be
a demand for additional EL triggered behaviors. By allowing these systems to
delegate administrative operations to their governing smart contracts, they can
avoid intermediaries needing to step in and ensure certain operations occur.
This creates a safer system for end users. By abstracting each individual request
details from the EL, adding new request types is simpler and does not require an
update on the execution block structure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution Layer&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;requests&quot;&gt;Requests&lt;&#x2F;h4&gt;
&lt;p&gt;A &lt;code&gt;requests&lt;&#x2F;code&gt; object consists of a &lt;code&gt;request_type&lt;&#x2F;code&gt; byte prepended to an opaque byte array
&lt;code&gt;request_data&lt;&#x2F;code&gt;. The &lt;code&gt;request_data&lt;&#x2F;code&gt; contains zero or more encoded request objects.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;requests = request_type ++ request_data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each request type will define its own &lt;code&gt;requests&lt;&#x2F;code&gt; object with its own &lt;code&gt;request_data&lt;&#x2F;code&gt; format.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;block-header&quot;&gt;Block Header&lt;&#x2F;h4&gt;
&lt;p&gt;Extend the header with a new 32 byte commitment value &lt;code&gt;requests_hash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While processing a block, multiple &lt;code&gt;requests&lt;&#x2F;code&gt; objects with different &lt;code&gt;request_type&lt;&#x2F;code&gt;s will
be produced by the system, and accumulated in the block requests list.&lt;&#x2F;p&gt;
&lt;p&gt;In order to compute the commitment, an intermediate hash list is first built by hashing
all non-empty requests elements of the block requests list. Items with empty
&lt;code&gt;request_data&lt;&#x2F;code&gt; are excluded, i.e. the intermediate list skips &lt;code&gt;requests&lt;&#x2F;code&gt; items which
contain only the &lt;code&gt;request_type&lt;&#x2F;code&gt; (1 byte) and nothing else.&lt;&#x2F;p&gt;
&lt;p&gt;Within the intermediate list, &lt;code&gt;requests&lt;&#x2F;code&gt; items must be ordered by &lt;code&gt;request_type&lt;&#x2F;code&gt; ascending.&lt;&#x2F;p&gt;
&lt;p&gt;The final commitment is computed as the sha256 hash of the intermediate element hashes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compute_requests_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;block_requests&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&gt;    m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; block_requests&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            m&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;digest&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;requests_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; compute_requests_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;requests&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;consensus-layer&quot;&gt;Consensus Layer&lt;&#x2F;h3&gt;
&lt;p&gt;Each proposal may choose how to extend the beacon chain types to include new EL request
types.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;opaque-byte-array-rather-than-an-rlp-array&quot;&gt;Opaque byte array rather than an RLP array&lt;&#x2F;h3&gt;
&lt;p&gt;By having the bytes of &lt;code&gt;request_data&lt;&#x2F;code&gt; array from second byte on be opaque bytes, rather
than an RLP (or other encoding) list, we can support different encoding formats for the
request payload in the future such as SSZ, LEB128, or a fixed width format.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;request-source-and-validity&quot;&gt;Request source and validity&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP makes no strict requirement where a request may come from nor when&#x2F;how
a request must be validated. This is to provide future protocol designers
maximum flexibility.&lt;&#x2F;p&gt;
&lt;p&gt;The authors&#x27; recommendations on source and validity of requests are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The source of requests should be from the execution of transactions. More
specifically, transactions which make calls to designated system contracts
that store the request in account. The storage would later be retrieved by a
post-block system call to the contract. Alternatively, if the system call does
not need to be inherently concerned with rate limiting, it could rely simply
on emitting an event which is later parsed post-block by the system and
converted into a request.&lt;&#x2F;li&gt;
&lt;li&gt;A request&#x27;s validity can often not be fully verified at the execution layer.
This is why they are referred to merely as &quot;requests&quot;; they do not carry the
authority on their own to unilaterally catalyze an action. We expect the system
contracts to perform whatever validation is possible by the EL and then pass
it on to the CL for further validation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ordering&quot;&gt;Ordering&lt;&#x2F;h3&gt;
&lt;p&gt;The ordering across types is ascending by type. This is to simplify the process
of verifying that all requests which were committed to in &lt;code&gt;requests_hash&lt;&#x2F;code&gt; match.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative could be to order by when the request was generated within the
block. Since it&#x27;s expected that many requests will be accumulated at the end of
the block via system calls, this would be difficult to enforce. Therefore,
ordering by type is the most straightforward ordering which ensures integrity.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;intra-type&quot;&gt;Intra-type&lt;&#x2F;h4&gt;
&lt;p&gt;Within the same type, order is not defined. This is because the data of the
request is opaque as far as this EIP is concerned. Therefore, it is to be
determined by each request type individually.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removing-empty-requests-in-commitment&quot;&gt;Removing empty requests in commitment&lt;&#x2F;h3&gt;
&lt;p&gt;We exclude empty requests elements from the &lt;code&gt;requests_hash&lt;&#x2F;code&gt; commitment in order to get a
stable &#x27;empty&#x27; hash value that is independent of the blockchain fork. For a block with no
requests data, the &lt;code&gt;requests_hash&lt;&#x2F;code&gt; is simply &lt;code&gt;sha256(&quot;&quot;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;TODO&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Needs discussion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Generalized Contract-Linked Services</title>
        <published>2024-03-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Francesco Sullo</name><uri>https://github.com/sullof</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7656/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/variation-to-erc6551-to-deploy-any-kind-of-contract-linked-to-an-nft/19223" />
        

        <id>https://wg-eips.ritovision.com/7656/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7656"
            label="ERC-7656" />
        

        
        

        
        <summary type="html">Define a factory for generic services linked to any contract type, including smart accounts and NFTs</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7656/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal defines a factory capable of deploying generic services linked to specific contracts, such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; accounts or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; tokens (NFTs). These linked services extend the functionalities of the target contract, operating under the ownership of the contract&#x27;s or NFT&#x27;s owner without requiring modifications to the original contract&#x27;s code. This approach enables extending existing contracts with new capabilities while maintaining backward compatibility with deployed instances.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Existing projects, like token-bound accounts, successfully bind smart accounts to NFTs, allowing registries to deploy accounts owned by specific token IDs. However, these standards have two key limitations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;They often require deployed contracts to implement specific interfaces for handling assets and executing transactions, effectively mandating that the deployed contract must function as an account.&lt;&#x2F;li&gt;
&lt;li&gt;They are restricted to NFTs, while many other contract types (particularly &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; accounts) could benefit from similar linking mechanisms to extend their functionalities.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This ERC proposes a more versatile factory specification that enables the deployment of proxies pointing to any contract that enhances the associated contract&#x27;s capabilities, whether it&#x27;s an NFT or an account contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-benefits&quot;&gt;Key Benefits&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Universal Linkability&lt;&#x2F;strong&gt;: Enables services to be linked to any compatible contract type, not just NFTs, creating a unified approach to contract extension.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Non-Invasive Enhancement&lt;&#x2F;strong&gt;: Services can add functionality to existing smart accounts without modifying the underlying contract, maintaining compatibility with infrastructure like wallets and indexers.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Backward Compatibility&lt;&#x2F;strong&gt;: Maintains compatibility with existing token-bound accounts while extending functionality to new use cases.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flexible Implementation&lt;&#x2F;strong&gt;: The &lt;code&gt;mode&lt;&#x2F;code&gt; parameter enables different linkage types (with or without token IDs) while ensuring consistent deterministic addressing.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unified Extension Mechanism&lt;&#x2F;strong&gt;: Provides a standardized approach for extending existing contracts with new capabilities, reducing the need for specialized implementations across different use cases.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;use-cases-for-erc-4337-smart-accounts&quot;&gt;Use Cases for ERC-4337 Smart Accounts&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Social Recovery Services&lt;&#x2F;strong&gt;: Deploy a social recovery mechanism linked to an existing ERC-4337 wallet that can restore access if credentials are lost, without requiring the wallet to implement recovery functionality natively.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Customizable Permission Systems&lt;&#x2F;strong&gt;: Add granular permissions to an account (time-limited access, spending limits, multi-signature approvals) without rebuilding the account from scratch.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Account Abstraction Extensions&lt;&#x2F;strong&gt;: Implement advanced features like batch transactions, gas sponsorship, or session keys as linked services, allowing wallets to adopt these features selectively.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Identity and Reputation Services&lt;&#x2F;strong&gt;: Link verifiable credentials or reputation systems to accounts, enabling privacy-preserving identity verification.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;use-cases-for-nfts&quot;&gt;Use Cases for NFTs&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enhanced Token Utility&lt;&#x2F;strong&gt;: Provide NFTs with financial capabilities like staking, lending, or revenue distribution.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dynamic Metadata Services&lt;&#x2F;strong&gt;: Enable NFT metadata to evolve based on on-chain activities without changing the NFT itself.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fractional Ownership&lt;&#x2F;strong&gt;: Implement fractional ownership mechanisms for high-value NFTs through linked contracts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conditional Access Control&lt;&#x2F;strong&gt;: Create time-locked or challenge-based access to NFT-gated content or services.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Real World Asset Management&lt;&#x2F;strong&gt;: Extend NFTs to represent and manage real-world assets (RWAs) by linking services that handle compliance, legal documentation, custody verification, transfer restrictions, and regulatory reporting without requiring specialized NFT standards for each asset class.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST,&quot; &quot;MUST NOT,&quot; &quot;REQUIRED,&quot; &quot;SHALL,&quot; &quot;SHALL NOT,&quot; &quot;SHOULD,&quot; &quot;SHOULD NOT,&quot; &quot;RECOMMENDED,&quot; &quot;NOT RECOMMENDED,&quot; &quot;MAY,&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;IERC7656Factory&lt;&#x2F;code&gt; interface is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7656Factory&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Created&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contractAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedId&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&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 class=&quot;z-storage z-type&quot;&gt;  error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CreationFailed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; service&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;linking-modes&quot;&gt;Linking Modes&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mode&lt;&#x2F;code&gt; parameter serves as a selector for how the linked contract should be interpreted and utilized. Currently, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; defines two standard modes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; NO_LINKED_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x000000000000000000000001&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; LINKED_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x000000000000000000000000&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LINKED_ID Mode (0x000000000000000000000000)&lt;&#x2F;strong&gt;: Used when linking a service to an NFT or any contract that requires a token&#x2F;entity ID. This mode ensures compatibility with existing token-bound account systems.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;NO_LINKED_ID Mode (0x000000000000000000000001)&lt;&#x2F;strong&gt;: Used when linking a service to a contract that doesn&#x27;t require an ID parameter, such as an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; account. In this case, the &lt;code&gt;linkedId&lt;&#x2F;code&gt; parameter is still present in the interface for consistency but SHOULD be set to zero if not used to store alternative data relevant to the service.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;mode&lt;&#x2F;code&gt; parameter (being &lt;code&gt;bytes12&lt;&#x2F;code&gt;) allows for future extensions beyond these initial modes, enabling more complex linkage patterns as ecosystem needs evolve.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deployment-requirements&quot;&gt;Deployment Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;Any &lt;code&gt;ERC7656Factory&lt;&#x2F;code&gt; implementation MUST support the &lt;code&gt;IERC7656Factory&lt;&#x2F;code&gt; interface ID (&lt;code&gt;0x9e23230a&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Each linked service MUST be deployed as an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1167&#x2F;&quot;&gt;ERC-1167&lt;&#x2F;a&gt; minimal proxy, appending immutable constant data to the bytecode. The deployed bytecode structure is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ERC-1167 Header               (10 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;implementation (address)&amp;gt;    (20 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ERC-1167 Footer               (15 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;salt (bytes32)&amp;gt;              (32 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;chainId (uint256)&amp;gt;           (32 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;mode (bytes12)&amp;gt;              (12 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;linkedContract (address)&amp;gt;    (20 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;linkedId (uint256)&amp;gt;          (32 bytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Total bytecode size: 183 bytes&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Linked services SHOULD implement the &lt;code&gt;IERC7656Service&lt;&#x2F;code&gt; interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface ID: 0x7e110a1d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7656Service&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; linkedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes12&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; linkedId&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;implementation-patterns&quot;&gt;Implementation Patterns&lt;&#x2F;h3&gt;
&lt;p&gt;When implementing a linked service, developers SHOULD consider the following patterns:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ownership Verification&lt;&#x2F;strong&gt;: Services SHOULD include mechanisms to verify that operations are authorized by the current owner of the linked contract or token.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mode-Specific Logic&lt;&#x2F;strong&gt;: Services SHOULD implement conditional logic based on the &lt;code&gt;mode&lt;&#x2F;code&gt; parameter to handle both NFT-linked and account-linked scenarios appropriately.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cross-Chain Awareness&lt;&#x2F;strong&gt;: Services SHOULD check that operations are being performed on the chain specified in the &lt;code&gt;chainId&lt;&#x2F;code&gt; parameter to prevent cross-chain replay attacks.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The design of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; is guided by several key principles that address limitations in current contract extension methods:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-a-unified-factory&quot;&gt;Why a Unified Factory?&lt;&#x2F;h3&gt;
&lt;p&gt;Rather than creating separate standards for NFT extensions and account extensions, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; employs a unified factory approach. This design choice stems from recognizing the fundamental similarity between linking services to tokens and linking services to accounts - both involve extending functionality while maintaining a clear ownership relationship.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mode-parameter-design&quot;&gt;Mode Parameter Design&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mode&lt;&#x2F;code&gt; parameter uses 12 bytes instead of a simple boolean flag because the 12-byte format reserves space for future linking modes beyond the initial two (NFT linking and account linking). For example, if a service is associated to an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; token but requires that the balance of the user is more than 1000 tokens, the mode could be &lt;code&gt;0x000000000000000000003e802&lt;&#x2F;code&gt;, where the least significant byte, &lt;code&gt;0x02&lt;&#x2F;code&gt; is the primary mode and the rest is the minimum required balance. Similarly, someone can think of a service associated to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens that requires a specific balance where the required balance can be put in the &lt;code&gt;linkedId&lt;&#x2F;code&gt; field, and the &lt;code&gt;mode&lt;&#x2F;code&gt; specified accordingly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deterministic-addressing&quot;&gt;Deterministic Addressing&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; follows a deterministic addressing pattern, appending immutable data to the contract bytecode rather than storing it in contract storage. This ensures that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Linked services have predictable addresses that can be computed off-chain&lt;&#x2F;li&gt;
&lt;li&gt;The factory remains stateless, reducing gas costs&lt;&#x2F;li&gt;
&lt;li&gt;Linked services can be deployed on-demand or even referenced before deployment&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;generic-linking-mechanism&quot;&gt;Generic Linking Mechanism&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike standards that enforce specific interfaces or behaviors on linked contracts, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; remains agnostic about the implementation details of linked services. This deliberate design choice allows developers maximum flexibility to create specialized services while maintaining a consistent deployment and ownership model.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; maintains compatibility with token-bound accounts when used with the &lt;code&gt;LINKED_ID&lt;&#x2F;code&gt; mode (0x000000000000000000000000). This ensures that existing applications and infrastructure supporting token-bound accounts can continue operating without modification.&lt;&#x2F;p&gt;
&lt;p&gt;For contracts using the &lt;code&gt;NO_LINKED_ID&lt;&#x2F;code&gt; mode (0x000000000000000000000001), specialized interfaces may be required, but the core factory mechanism remains consistent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;.&#x2F;assets&#x2F;ERC7656Factory.sol&quot;&gt;&lt;code&gt;ERC7656Factory.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; for an example implementation of &lt;code&gt;IERC7656Factory&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For convenience, the bytecode of the reference implementation has been deployed at &lt;code&gt;0x76565d90eeB1ce12D05d55D142510dBA634a128F&lt;&#x2F;code&gt; on Ethereum mainnet, and will be later deployed at the same address to all primary mainnets and selected testnets.&lt;&#x2F;p&gt;
&lt;p&gt;An example of implementation of &lt;code&gt;IERC7656Service&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; LinkedService&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7656Service&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;EIP5313&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; linkedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; service&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; encodedData &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; solhint-disable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-next-line no-inline-assembly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Copy 0x60 bytes from end of context&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;      extcodecopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;encodedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x4d&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x60&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; linkedContract&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; linkedId&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; solhint-disable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-next-line no-inline-assembly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;      chainId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;encodedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x20&lt;&#x2F;span&gt;&lt;span&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&gt;      linkedContract &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;encodedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x40&lt;&#x2F;span&gt;&lt;span&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&gt;      linkedId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;encodedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x60&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-support&quot;&gt;    bytes12&lt;&#x2F;span&gt;&lt;span&gt; mode &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes12&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;linkedContract&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; extractedAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint160&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;linkedContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; extractedAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; linkedId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; tokenContract_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; linkedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;chainId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenContract_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId_&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ownership-cycles&quot;&gt;Ownership Cycles&lt;&#x2F;h3&gt;
&lt;p&gt;Smart wallets linked to NFTs that are then held by the same wallet can create ownership cycles, potentially rendering assets inaccessible. Implementers should include safeguards to prevent or detect such cycles.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fraud-prevention&quot;&gt;Fraud Prevention&lt;&#x2F;h3&gt;
&lt;p&gt;A malicious seller could alter or revoke service permissions just before finalizing a sale. Lock mechanisms preventing last-minute changes may be implemented, especially for NFT marketplaces integrating with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; services.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;malicious-implementations&quot;&gt;Malicious Implementations&lt;&#x2F;h3&gt;
&lt;p&gt;The registry cannot enforce legitimate ownership when linking services. Users should review or audit implementations before deployment. Front-end applications integrating &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt; should display warnings when interacting with unverified implementations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;upgradeability-risks&quot;&gt;Upgradeability Risks&lt;&#x2F;h3&gt;
&lt;p&gt;Linked services that are upgradable pose risks of unexpected changes or asset exfiltration. Secure upgrade mechanisms with timelock controls or multi-signature governance should be implemented when upgradeability is required.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reentrancy-cross-contract-attacks&quot;&gt;Reentrancy &amp;amp; Cross-Contract Attacks&lt;&#x2F;h3&gt;
&lt;p&gt;Linked services interacting with assets or external protocols may be vulnerable to reentrancy exploits. Implementers should follow security best practices such as the checks-effects-interactions pattern and consider reentrancy guards.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mode-specific-vulnerabilities&quot;&gt;Mode-Specific Vulnerabilities&lt;&#x2F;h3&gt;
&lt;p&gt;Services operating in different modes (&lt;code&gt;LINKED_ID&lt;&#x2F;code&gt; vs &lt;code&gt;NO_LINKED_ID&lt;&#x2F;code&gt;) may have different security requirements. Implementations should validate that operations are appropriate for the service&#x27;s configured mode.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;user-education-phishing-risks&quot;&gt;User Education &amp;amp; Phishing Risks&lt;&#x2F;h3&gt;
&lt;p&gt;Even with secure contracts, users may fall victim to fraudulent services masquerading as legitimate ones. Clear UI warnings, verification tools, and educational resources should be provided by applications integrating &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7656&#x2F;&quot;&gt;ERC-7656&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>eth&#x2F;69 - history expiry and simpler receipts</title>
        <published>2024-02-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	<author>
		<name>Felix Lange</name><email>fjl@ethereum.org</email>
	</author>
	
	<author>
		<name>Ahmad Bitar</name><uri>https://github.com/smartprogrammer93</uri><email>smartprogrammer@windowslive.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7642/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eth-70-drop-pre-merge-fields-from-eth-protocol/19005" />
        

        <id>https://wg-eips.ritovision.com/7642/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7642"
            label="EIP-7642" />
        

        
        

        
        <summary type="html">Adds history serving window and removes bloom filter in receipt</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7642/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP modifies the &#x27;eth&#x27; p2p protocol to announce the historical block range served by
the node. We also simplify the handshake to remove total difficulty information, which
isn&#x27;t used anymore after the merge. Additionally we propose to remove the &lt;code&gt;Bloom&lt;&#x2F;code&gt; field
from receipts transferred over the protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;block-range-in-status-message&quot;&gt;Block range in Status message&lt;&#x2F;h3&gt;
&lt;p&gt;In the history expiry working group, it was decided that clients may drop pre-merge
history from their storage after May 1, 2025. For clients that want to sync history
through the &#x27;eth&#x27; protocol, it is essential to know whether a peer still serves old
history. A similar idea was proposed in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7542&#x2F;&quot;&gt;EIP-7542&lt;&#x2F;a&gt; but was later withdrawn
because a political decision on history expiry had not been reached at the time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removing-bloom-in-receipts&quot;&gt;Removing Bloom in Receipts&lt;&#x2F;h3&gt;
&lt;p&gt;We recently discovered that none of the clients store the &lt;code&gt;Bloom&lt;&#x2F;code&gt; field of the receipts as
it can be recomputed on demand. However the networking spec requires the &lt;code&gt;Bloom&lt;&#x2F;code&gt; field to
be sent over the network. Thus a syncing node will ask for the Bloom filters for all
receipts. The serving node will regenerate roughly 530GB of bloom filters (2.3B txs * 256
byte). These 530GBs are send over the network to the syncing peer, the syncing peer will
verify them and not store them either. This adds an additional 530GB of unnecessary
bandwidth to every sync.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blockrangeupdate-message&quot;&gt;BlockRangeUpdate message&lt;&#x2F;h3&gt;
&lt;p&gt;We want clients to be aware of the available block range in their peers. The new
notification message can be used to detect sync status of peers, and adjust fetching
behavior accordingly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;status-message-changes&quot;&gt;Status message changes&lt;&#x2F;h3&gt;
&lt;p&gt;Modify the &lt;code&gt;Status (0x00)&lt;&#x2F;code&gt; message as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;(eth&#x2F;68): &lt;code&gt;[version: P, networkid: P, td: P, blockhash: B_32, genesis: B_32, forkid]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;(eth&#x2F;69): &lt;code&gt;[version: P, networkid: P, genesis: B_32, forkid, earliestBlock: P, latestBlock: P, latestBlockHash: B_32]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note &lt;code&gt;blockhash&lt;&#x2F;code&gt; has moved to the end to match &lt;code&gt;BlockRangeUpdate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;receipts-message-changes&quot;&gt;Receipts message changes&lt;&#x2F;h3&gt;
&lt;p&gt;Modify the encoding for receipts in the &lt;code&gt;Receipts (0x10)&lt;&#x2F;code&gt; message as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;(eth&#x2F;68): &lt;code&gt;receipt = {legacy-receipt, typed-receipt}&lt;&#x2F;code&gt; with&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typed-receipt = tx-type || rlp(legacy-receipt)&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;legacy-receipt = [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    post-state-or-status: {B_32, {0, 1}},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cumulative-gas: P,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bloom: B_256,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    logs: [log₁, log₂, ...]&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;ul&gt;
&lt;li&gt;(eth&#x2F;69): &lt;code&gt;receipt = [tx-type, post-state-or-status, cumulative-gas, logs]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;blockrangeupdate-message-1&quot;&gt;BlockRangeUpdate message&lt;&#x2F;h3&gt;
&lt;p&gt;Add a new &lt;code&gt;BlockRangeUpdate (0x11)&lt;&#x2F;code&gt; message, with the following encoding&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;[earliestBlock: P, latestBlock: P, latestBlockHash: B_32]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The new message should be sent whenever the block range available from this client is
updated. In order to reduce traffic, it is not necessary to send an update for every new
block. Clients should send an update at most once per epoch (32 blocks).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;status-changes&quot;&gt;Status changes&lt;&#x2F;h3&gt;
&lt;p&gt;After the merge, the &lt;code&gt;TD&lt;&#x2F;code&gt; field of the &lt;code&gt;Status&lt;&#x2F;code&gt; message became meaningless since the
difficulty of post-merge blocks are 0. It could in theory be used to distinguish synced
with unsynced nodes, but the same thing can be accomplished with the forkid as well.&lt;&#x2F;p&gt;
&lt;p&gt;The new &lt;code&gt;earliestBlock&lt;&#x2F;code&gt; field is technically not required for history expiry, but there
are a couple reasons why adding it can help:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It improves peer finding for clients that still want to sync history from p2p after the
agreed-upon removal of pre-merge history has taken place. Without &lt;code&gt;earliestBlock&lt;&#x2F;code&gt;, the
client would have to perform a request for history to check if the earlier range exists,
and assume that a failed request means it&#x27;s not there.&lt;&#x2F;li&gt;
&lt;li&gt;The new field can be used for census in a specialized crawler. We will be able to see
how many users&#x2F;nodes enable history, and in which implementation.&lt;&#x2F;li&gt;
&lt;li&gt;It prepares us for a future where the history expiry window is dynamic.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;receipts-changes&quot;&gt;Receipts changes&lt;&#x2F;h3&gt;
&lt;p&gt;Removing the bloom filters from the &lt;code&gt;Receipt&lt;&#x2F;code&gt; message reduces the CPU load of serving
nodes as well as the bandwidth significantly. The receiving nodes will need to recompute
the bloom filter in order to fully verify the receipt hash. The recomputation is not very
CPU intensive. The bandwidth gains amount to roughly 530GiB per syncing node or (at least)
95GiB snappy compressed.&lt;&#x2F;p&gt;
&lt;p&gt;In Ethereum consensus, the encoding of receipts differs between legacy transactions and
typed transactions. Typed transaction receipts are &#x27;opaque&#x27; and have the data wrapped in a
byte array. However, all receipt types ultimately contain the same four fields. With the
removal of the bloom filter, the networking protocol now deviates from the encoding used
by consensus, and there is no need to replicate the weird and expensive encoding used
there. The proposed receipt encoding is just a flat list of the required data fields.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP changes the eth protocol and requires rolling out a new version, &lt;code&gt;eth&#x2F;69&lt;&#x2F;code&gt;.
Supporting multiple versions of a wire protocol is possible. Rolling out a new version
does not break older clients immediately, since they can keep using protocol version
&lt;code&gt;eth&#x2F;68&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change consensus rules of the EVM and does not require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Limited Transfer Count NFT</title>
        <published>2024-02-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Qin Wang</name><uri>https://github.com/qinwang-git</uri>
	</author>
	
	<author>
		<name>Saber Yu</name><uri>https://github.com/OniReimu</uri>
	</author>
	
	<author>
		<name>Shiping Chen</name><email>shiping.chen@data61.csiro.au</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7634/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7634-limited-transferable-nft/18861" />
        

        <id>https://wg-eips.ritovision.com/7634/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:7634"
            label="ERC-7634" />
        

        
        

        
        <summary type="html">An ERC-721 extension that caps how many times an individual token can be transferred</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7634/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; with a mechanism that lets token owners&#x2F;minters cap how many times a specific token can be transferred. It specifies functions to set and read a per-token transfer limit, to query a per-token transfer count, and defines transfer-time hooks to enforce the cap. The goal is fine-grained, enforceable transfer restrictions while preserving ERC-721 compatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Once NFTs are sold, they detach from their minters and can be perpetually transferred. Yet many situations require tighter control over secondary movement.&lt;&#x2F;p&gt;
&lt;p&gt;First, limiting the number of transfers can help preserve value (e.g., premium auctions, IP that becomes CC0 after a finite number of transfers, or game items that “wear out” and burn at a threshold).&lt;&#x2F;p&gt;
&lt;p&gt;Second, capping transfer frequency can reduce risks from adversarial arbitrage (e.g., HFT-like behavior) by offering an easy-to-deploy throttle.&lt;&#x2F;p&gt;
&lt;p&gt;Third, bounding re-staking cycles of NFT positions (e.g., proof-of-restake) can dampen recursive leverage and mitigate bubble dynamics.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Controlled Value Preservation.&lt;&#x2F;em&gt; Scarcity via a transfer cap can help maintain value over time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Ensuring Intended Usage.&lt;&#x2F;em&gt; Limits keep usage aligned with intent (e.g., limited editions less prone to flip cycles).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Expanding Use Cases.&lt;&#x2F;em&gt; Memberships&#x2F;licenses with bounded transferability become practical.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Easy Integration.&lt;&#x2F;em&gt; An extension interface (&lt;code&gt;IERC7634&lt;&#x2F;code&gt;) layers on top of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, easing adoption without breaking compatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setTransferLimit&lt;&#x2F;code&gt;: establishes the transfer limit for a &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;transferLimitOf&lt;&#x2F;code&gt;: returns the transfer limit for a &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;transferCountOf&lt;&#x2F;code&gt;: returns the current transfer count for a &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Counting and enforcement scope.&lt;&#x2F;strong&gt; Implementations &lt;strong&gt;MUST&lt;&#x2F;strong&gt; enforce the cap on native ERC-721 transfers of the underlying token (i.e., transfers where &lt;code&gt;from != address(0)&lt;&#x2F;code&gt; and &lt;code&gt;to != address(0)&lt;&#x2F;code&gt;). Incrementing the count &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; occur only after a successful native transfer. Mint and burn operations MUST NOT increment the count.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers &lt;strong&gt;MUST&lt;&#x2F;strong&gt; provide the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC7634 Interface for Transfer-Capped ERC-721 Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7634 is an extension interface intended to be implemented alongside ERC-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7634&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted after a successful native transfer when the per-token count increases.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferCountIncreased&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newCount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the per-token transfer limit is set or updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferLimitUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; previousLimit&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newLimit&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current transfer count for a tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the transfer limit for a tokenId. Callable by owner or approved.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token id to set the limit for.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The maximum number of native transfers allowed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTransferLimit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; limit&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the transfer limit for a tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferLimitOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tracking-and-hooks&quot;&gt;Tracking and hooks&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;transferCountOf&lt;&#x2F;code&gt; and &lt;code&gt;transferLimitOf&lt;&#x2F;code&gt; expose state needed to enforce a cap. The count should only increase after a successful native transfer (not on mint&#x2F;burn). Separating &lt;code&gt;TransferLimitUpdated&lt;&#x2F;code&gt; from &lt;code&gt;TransferCountIncreased&lt;&#x2F;code&gt; makes it clear that the former is an administrative change while the latter is derived from runtime transfers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. Existing contracts can adopt it by adding the new interface and hooks without changing ERC-721 semantics.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extensions&quot;&gt;Extensions&lt;&#x2F;h3&gt;
&lt;p&gt;This standard can be enhanced with additional advanced functionalities alongside existing NFT protocols. For example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Incorporating a burn function (e.g., &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5679&#x2F;&quot;&gt;ERC-5679&lt;&#x2F;a&gt;) would enable NFTs to automatically expire after reaching their transfer limits, akin to the ephemeral nature of Snapchat messages that disappear after multiple views.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Incorporating a non-transferring function, as defined in the SBT standards, would enable NFTs to settle and bond with a single owner after a predetermined number of transactions. This functionality mirrors the scenario where a bidder ultimately secures a treasury after participating in multiple bidding rounds.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Below is a recommended pattern. It enforces the cap pre-transfer, increments the count post-transfer, ignores mint&#x2F;burn for counting, and emits the clarified events. Implementations commonly override &lt;code&gt;_beforeTokenTransfer&lt;&#x2F;code&gt; to enforce &lt;code&gt;transferCount&lt;&#x2F;code&gt; &amp;lt; &lt;code&gt;transferLimit&lt;&#x2F;code&gt; and &lt;code&gt;_afterTokenTransfer&lt;&#x2F;code&gt; to increment the count and emit &lt;code&gt;TransferCountIncreased&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC7634.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer-Capped ERC-721 (ERC-7634)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example implementation of ERC-7634 alongside ERC-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7634&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7634&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; tokenId =&amp;gt; current transfer count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _transferCounts&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; tokenId =&amp;gt; max allowed native transfers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _transferLimits&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7634: nonexistent token&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _transferCounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTransferLimit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; limit&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7634: not owner&#x2F;approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; prev &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _transferLimits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        _transferLimits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; limit&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferLimitUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; prev&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; limit&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferLimitOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7634: nonexistent token&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _transferLimits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enforce transfer limit on native transfers (exclude mint&#x2F;burn).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;                _transferCounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _transferLimits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                &amp;quot;ERC7634: transfer limit reached&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increment count only after successful native transfer and emit event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _afterTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; quantity&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            unchecked&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; _transferCounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferCountIncreased&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _transferCounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_transferCounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _transferLimits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Optional: perform action exactly when the cap is reached (e.g., _burn(tokenId))&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_afterTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; quantity&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        virtual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC7634&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scope with wrappers. The cap applies only to native &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; transfers of the underlying token. Any owner can cheaply wrap a token and transfer a separate wrapper token; such downstream transfers cannot be prevented without breaking &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; composability. As a result, this standard does not provide an unbypassable guarantee that, for example, a game item will always wear out or that secondary trading is globally capped; it standardizes a primitive for budgeting native transfers that ecosystems may choose to coordinate around. Deployments that want stronger effective guarantees &lt;strong&gt;MAY&lt;&#x2F;strong&gt; add optional mitigations such as recipient allowlists&#x2F;registries or &quot;compliant wrapper&quot; patterns that mirror counts&#x2F;limits, trading off openness for enforcement.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Limit mutability. Consider making limits immutable once set (or only decreasing), to prevent tampering.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Gas. Avoid heavy logic in hooks; extensions (e.g., burn on cap) should remain gas-safe.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Dual Nature Token Pair</title>
        <published>2024-02-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>vectorized</name><uri>https://github.com/vectorized</uri>
	</author>
	
	<author>
		<name>Thomas</name><uri>https://github.com/0xth0mas</uri>
	</author>
	
	<author>
		<name>Quit</name><uri>https://github.com/quitcrypto</uri>
	</author>
	
	<author>
		<name>Michael Amadi</name><uri>https://github.com/AmadiMichael</uri>
	</author>
	
	<author>
		<name>cygaar</name><uri>https://github.com/cygaar</uri>
	</author>
	
	<author>
		<name>Harrison</name><uri>https://github.com/pop-punk</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7631/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7631-dual-nature-token-pair/18796" />
        

        <id>https://wg-eips.ritovision.com/7631/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7631"
            label="ERC-7631" />
        

        
        

        
        <summary type="html">A specification for a co-joined fungible and non-fungible token pair</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7631/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A fungible &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token contract and non-fungible &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; token contract can be interlinked, allowing actions performed on one contract to be reflected on the other. This proposal defines how the relationship between the two token contracts can be queried. It also enables accounts to configure whether ERC-721 mints and transfers should be skipped during ERC-20 to ERC-721 synchronization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The ERC-20 fungible and ERC-721 non-fungible token standards offer sufficient flexibility for a co-joined, dual nature token pair. Transfers on the ERC-20 token can automatically trigger transfers on the ERC-721 token, and vice-versa. This enables applications such as native ERC-721 fractionalization, wherein acquiring ERC-20 tokens leads to the automatic issuance of ERC-721 tokens, proportional to the ERC-20 balance.&lt;&#x2F;p&gt;
&lt;p&gt;Dual nature token pairs maintain full compliance with both ERC-20 and ERC-721 token standards. This proposal aims to enhance the functionality of dual nature token pairs.&lt;&#x2F;p&gt;
&lt;p&gt;To facilitate querying the relationship between the tokens, extension interfaces are proposed for the ERC-20 and ERC-721 tokens respectively. This enables various quality of life improvements such as allowing decentralized exchanges and NFT marketplaces to display the relationship between the tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, users can configure whether they want to skip ERC-721 mints and transfers during ERC-20 to ERC-721 synchronization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;A dual nature token pair comprises of an ERC-20 contract and an ERC-721 contract.&lt;&#x2F;p&gt;
&lt;p&gt;For convention, the ERC-20 contract is designated as the base contract, and the ERC-721 contract is designated as the mirror contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-20-extension-interface&quot;&gt;ERC-20 Extension Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The ERC-20 contract MUST implement the following interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7631Base&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the address of the mirror ERC-721 contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MAY revert or return the zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to denote that a mirror ERC-721 contract has not been linked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If a non-zero address is returned, the returned address MUST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; implement `IERC7631Mirror` and its `baseERC20()` method MUST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; return the address of this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Once a non-zero address has been returned, this method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST NOT revert and the returned value MUST NOT change.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mirrorERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The ERC-20 contract MAY implement the following interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7631BaseNFTSkippable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Implementations SHOULD emit this event when the skip NFT status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of `owner` is updated to `status`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The purpose of this event is to signal to indexers that the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; skip NFT status has been &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For simplicity of implementation,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this event MAY be emitted even if the status is unchanged.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SkipNFTSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; status&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if ERC-721 mints and transfers to `owner` SHOULD be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; skipped during ERC-20 to ERC-721 synchronization.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Otherwise, returns false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MAY revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (e.g. contract not initialized, method not supported).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If this method reverts:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Interacting code SHOULD interpret `setSkipNFT` functionality as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   unavailable and hide any functionality to call `setSkipNFT`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The skip NFT status for `owner` SHOULD be interpreted as undefined.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Once a true or false value has been returned for a given `owner`,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this method MUST NOT revert for the given `owner`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getSkipNFT&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the caller&amp;#39;s skip NFT status.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MAY revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (e.g. insufficient permissions, method not supported).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is RECOMMENDED to keep this method permissionless.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits a {SkipNFTSet} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setSkipNFT&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-721-extension-interface&quot;&gt;ERC-721 Extension Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The ERC-721 contract MUST implement the following interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7631Mirror&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the address of the base ERC-20 contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MAY revert or return the zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to denote that a base ERC-20 contract has not been linked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If a non-zero address is returned, the returned address MUST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; implement `IERC7631Base` and its `mirrorERC721()` method MUST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; return the address of this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Once a non-zero address has been returned, this method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST NOT revert and the returned value MUST NOT change.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; baseERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;implementation-detection&quot;&gt;Implementation Detection&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mirrorERC721&lt;&#x2F;code&gt; and &lt;code&gt;baseERC20&lt;&#x2F;code&gt; methods returning non-zero addresses signal that the ERC-20 and ERC-721 contracts implement the required interfaces respectively. As such, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; is not required.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;getSkipNFT&lt;&#x2F;code&gt; and &lt;code&gt;setSkipNFT&lt;&#x2F;code&gt; methods MAY revert. As contracts compiled with Solidity or Vyper inherently revert on calls to undefined methods, a typical &lt;code&gt;IERC7631Base&lt;&#x2F;code&gt; implementation lacking explicit &lt;code&gt;getSkipNFT&lt;&#x2F;code&gt; and &lt;code&gt;setSkipNFT&lt;&#x2F;code&gt; definitions still complies with &lt;code&gt;IERC7631BaseNFTSkippable&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nft-skipping&quot;&gt;NFT Skipping&lt;&#x2F;h3&gt;
&lt;p&gt;The skip NFT methods allow accounts to avoid having ERC-721 tokens automatically minted to it whenever there is an ERC-20 transfer.&lt;&#x2F;p&gt;
&lt;p&gt;They are helpful in the following situations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Loading vesting contracts with large amounts ERC-20 tokens to be vested to many users.&lt;&#x2F;li&gt;
&lt;li&gt;Loading candy machine contracts with large amounts of ERC-20 tokens to sell ERC-721 tokens to customers.&lt;&#x2F;li&gt;
&lt;li&gt;Transferring large amounts of ERC-20 tokens in &#x2F; out of a liquidity pool.&lt;&#x2F;li&gt;
&lt;li&gt;Transferring large amounts of ERC-20 tokens between admin accounts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Including the skip NFT methods in the standard will:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Enable applications to conveniently display the option for users to skip NFTs.&lt;&#x2F;li&gt;
&lt;li&gt;Enable applications to transfer any amount of ERC-20 tokens without the O(n) gas costs associated with minting multiple ERC-721 tokens, which can surpass the block gas limit.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These methods are recommended even on EVM chains with low gas costs, because bulk automatic ERC-721 transfers can still surpass the block gas limit.&lt;&#x2F;p&gt;
&lt;p&gt;A useful pattern is to make &lt;code&gt;getSkipNFT&lt;&#x2F;code&gt; return true by default if &lt;code&gt;owner&lt;&#x2F;code&gt; is a smart contract.&lt;&#x2F;p&gt;
&lt;p&gt;The choice of &lt;code&gt;getSkipNFT&lt;&#x2F;code&gt; returning a boolean value is for simplicity. If more complex behavior is needed, developers may add in extra methods of their own.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation-conventions&quot;&gt;Implementation Conventions&lt;&#x2F;h3&gt;
&lt;p&gt;The ERC-20 contract is designated as the base contract for convention, as a typical implementation can conveniently derive ERC-721 balances from the ERC-20 balances. This does not prohibit one from implementing most of the logic in the ERC-721 contract if required.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal does not cover the token synchronization logic. This is to leave flexibility for various implementation patterns and novel use cases (e.g. automatically rebased tokens).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linking-mechanism&quot;&gt;Linking Mechanism&lt;&#x2F;h3&gt;
&lt;p&gt;The linking process is omitted for flexibility purposes. Developers can use any desired mechanism (e.g. linking in constructor, initializer, or via custom admin-only public methods on the two contracts). The only restriction is that the pairing must be immutable once established (to simplify indexing logic).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;synchronization-access-guards&quot;&gt;Synchronization Access Guards&lt;&#x2F;h3&gt;
&lt;p&gt;External methods for synchronization logic must be guarded such that only the other contract is authorized to call them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rare-nft-sniping&quot;&gt;Rare NFT Sniping&lt;&#x2F;h3&gt;
&lt;p&gt;For dual nature collections that offer ERC-721 tokens with differing rarity levels, the ERC-721 metadata should be revealed in a way that is not easily gameable with metadata scraping and ERC-20 token transfers. A recommendation is to require that an ERC-721 token is held by the same account for some time before revealing its metadata.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;out-of-gas-denial-of-service&quot;&gt;Out-of-gas Denial of Service&lt;&#x2F;h3&gt;
&lt;p&gt;Transferring ERC-20 tokens can automatically initiate the minting, transferring, or burning of multiple ERC-721 tokens. This can incur O(n) gas costs instead of the typical O(1) gas costs for ERC-20 tokens transfers. Logic for selecting ERC-721 token IDs can also incur additional gas costs. Synchronization logic must consider ERC-721 related gas costs to prevent out-of-gas denial of service issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Secure Messaging Protocol</title>
        <published>2024-02-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Chen Liaoyuan</name><uri>https://github.com/chenly</uri><email>cly@kip.pro</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7627/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7627-secure-messaging-protocol/18761" />
        

        <id>https://wg-eips.ritovision.com/7627/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7627"
            label="ERC-7627" />
        

        
        

        
        <summary type="html">End-to-end encryption for sending messages between users.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7627/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal implements the capability to securely exchange encrypted messages on-chain. Users can register their public keys and encryption algorithms by registration and subsequently send encrypted messages to other users using their addresses. The interface also includes enumerations for public key algorithms and a structure for user information to support various encryption algorithms and user information management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the emergence of Layer 2 chains featuring sub-second block times and the introduction of account abstraction, the use of end-to-end encrypted communication has facilitated the proliferation of real-time communication and online chat dApps. Providing a unified interface enables easy integration of encrypted communication into smart contracts, thereby fostering innovation. Standardization promotes interoperability, facilitating seamless communication across platforms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;objectives&quot;&gt;Objectives&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Provide a standardized interface for implementing messaging systems in smart contracts, including user registration and message sending functionalities.&lt;&#x2F;li&gt;
&lt;li&gt;Enhance flexibility and scalability for messaging systems by defining enumerations for public key algorithms and a structure for user information.&lt;&#x2F;li&gt;
&lt;li&gt;Define events for tracking message sending to enhance the observability and auditability of the contract.&lt;&#x2F;li&gt;
&lt;li&gt;Using a custom sessionId allows messages to be organized into a conversation.&lt;&#x2F;li&gt;
&lt;li&gt;Encrypt message content using the recipient&#x27;s public key during message transmission.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers of this standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have all of the following functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7627&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKeyAlgorithm&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; ECDSA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; ED25519&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; X25519&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKey&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt; public_key&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; valid_before&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        PublicKeyAlgorithm algorithm&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when a message is sent between users.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the recipient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index of the public key used to encrypt the message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sessionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The session ID for the communication&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; encryptedMessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The encrypted message in bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MessageSent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sessionId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; encryptedMessage&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when a user&amp;#39;s public key is updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the user whose public key is updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index of the public key being updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newPublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new public key data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKeyUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newPublicKey&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Functions&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 class=&quot;z-comment&quot;&gt;	&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Updates the public key for the sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index of the key to be updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _publicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new public key data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updatePublicKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _publicKey&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sends an encrypted message to a specified address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index of the public key used to encrypt the message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _sessionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The session ID for the communication&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _encryptedMessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The encrypted message in bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sendMessage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _sessionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _encryptedMessage&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves a public key for a specific user and key index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index of the key to retrieve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; public key data associated with the user and key index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getUserPublicKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;event-emission-for-off-chain-integration&quot;&gt;Event Emission for Off-Chain Integration&lt;&#x2F;h3&gt;
&lt;p&gt;By emitting events when messages are sent or public keys are updated, the implementation facilitates seamless integration with off-chain dApps. This enables these dApps to easily track and display the latest messages and updates, ensuring real-time responsiveness and enhancing user interaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;end-to-end-encryption-security&quot;&gt;End-to-End Encryption Security&lt;&#x2F;h3&gt;
&lt;p&gt;The design ensures that only the owner of an address can update their public key. This restriction preserves the integrity of the end-to-end encryption, making sure that only the intended recipient can decrypt and read the messages, thereby securing communication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;session-id-for-conversation-organization&quot;&gt;Session ID for Conversation Organization&lt;&#x2F;h3&gt;
&lt;p&gt;The use of session IDs in message transactions allows multiple messages to be grouped under specific conversations. This feature is crucial for organizing and managing discussions within a dApp, providing users with a coherent and structured messaging experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7627&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enum to specify the algorithm used for the public key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKeyAlgorithm&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; ECDSA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; ED25519&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; X25519&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Structure to represent a user&amp;#39;s public key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKey&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt; public_key&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; valid_before&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        PublicKeyAlgorithm algorithm&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mapping to store public keys for each address. The mapping is by user address and a unique key index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; PublicKey&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; pk&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MessageSent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sessionId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; encryptedMessage&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKeyUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keyIndex&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newPublicKey&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updatePublicKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _publicKey&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        pk&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_keyIndex&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _publicKey&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicKeyUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _publicKey&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sendMessage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _sessionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _encryptedMessage&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MessageSent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _sessionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _encryptedMessage&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getUserPublicKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyIndex&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;PublicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; pk&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_user&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_keyIndex&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;utilization-of-latest-secure-encryption-algorithms&quot;&gt;Utilization of Latest Secure Encryption Algorithms&lt;&#x2F;h4&gt;
&lt;p&gt;When selecting encryption algorithms, it is essential to stay informed about the latest security news and recommendations. Avoid using asymmetric encryption algorithms with known vulnerabilities or those not recommended to ensure the confidentiality and integrity of messages. Regularly update encryption algorithms to address evolving security threats.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;strict-encryption-using-public-keys-for-message-content&quot;&gt;Strict Encryption Using Public Keys for Message Content&lt;&#x2F;h4&gt;
&lt;p&gt;To maintain message confidentiality, the content of sent messages must be strictly encrypted using the recipient&#x27;s public key. Any plaintext information transmitted could lead to information leakage and security risks. Encrypt message content at all times during transmission and storage to prevent unauthorized access to sensitive information.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;key-management-and-protection&quot;&gt;Key Management and Protection&lt;&#x2F;h4&gt;
&lt;p&gt;Robust key management and protection measures are necessary for both user public and private keys. Ensure secure storage and transmission of keys to prevent leakage and tampering. Employ multi-factor authentication and key rotation strategies to enhance key security and regularly assess key management processes to mitigate potential security risks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Increase calldata cost</title>
        <published>2024-02-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7623/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7623-increase-calldata-cost/18647" />
        

        <id>https://wg-eips.ritovision.com/7623/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7623"
            label="EIP-7623" />
        

        
        

        
        <summary type="html">Increase calldata cost to reduce maximum block size</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7623/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The current calldata pricing permits EL payloads of up to 7.15 MB, while the average size is much smaller at around 100 KB.
This EIP proposes adjusting the calldata cost to reduce the maximum possible block size and its variance without negatively impacting regular users.
This is achieved by increasing calldata costs for transactions that predominantly post data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The block gas limit has not been increased since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt;, while the average size of blocks has continuously increased due to the growing number of rollups posting data to Ethereum. Moreover, calldata costs have remained unchanged since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2028&#x2F;&quot;&gt;EIP-2028&lt;&#x2F;a&gt;.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; introduces blobs as a preferred method for data availability (DA).
This transition demands a reevaluation of calldata pricing, especially in order to address the disparity between average and maximum block sizes.
By introducing a floor cost dependent on the ratio of gas spent on EVM operations to calldata, this proposal aims to reduce the maximum block size to make room for additional blobs or potential block gas limit increases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;STANDARD_TOKEN_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TOTAL_COST_FLOOR_PER_TOKEN&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Let &lt;code&gt;tokens_in_calldata = zero_bytes_in_calldata + nonzero_bytes_in_calldata * 4&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;code&gt;isContractCreation&lt;&#x2F;code&gt; be a boolean indicating the respective event.&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;code&gt;execution_gas_used&lt;&#x2F;code&gt; be the gas used for EVM execution with the gas refund subtracted.&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;code&gt;INITCODE_WORD_COST&lt;&#x2F;code&gt; be 2 as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3860&#x2F;&quot;&gt;EIP-3860&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The current formula for determining the total gas used per transaction (&lt;code&gt;tx.gasUsed&lt;&#x2F;code&gt;) is equivalent to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-constant&quot;&gt;    21000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; STANDARD_TOKEN_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; tokens_in_calldata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span&gt; execution_gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span&gt; isContractCreation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; INITCODE_WORD_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; words&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&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&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The formula for determining the gas used per transaction changes to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-constant&quot;&gt;    21000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        STANDARD_TOKEN_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; tokens_in_calldata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        +&lt;&#x2F;span&gt;&lt;span&gt; execution_gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        +&lt;&#x2F;span&gt;&lt;span&gt; isContractCreation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; INITCODE_WORD_COST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; words&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;        TOTAL_COST_FLOOR_PER_TOKEN&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; tokens_in_calldata&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;Any transaction with a gas limit below &lt;code&gt;21000 + TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata&lt;&#x2F;code&gt; or below its intrinsic gas cost (take the maximum of these two calculations) is considered invalid. This limitation exists because transactions must cover the floor price of their calldata without relying on the execution of the transaction. There are valid cases where &lt;code&gt;gasUsed&lt;&#x2F;code&gt; will be below this floor price, but the floor price needs to be reserved in the transaction gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The current maximum EL payload size is approximately 1.79 MB (&lt;code&gt;30_000_000&#x2F;16&lt;&#x2F;code&gt;). It is possible to create payloads filled with zero bytes that expand to 7.15 MB. However, since blocks are typically compressed with Snappy at the P2P layer, zero-byte-heavy EL payloads generally compress to under 1.79 MB. The implementation of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; increased the maximum possible compressed block size to approximately 2.54 MB.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal aims to increase the cost of calldata to 10&#x2F;40 gas for transactions that do not exceed a certain threshold of gas spent on EVM operations relative to gas spent on calldata. This change will significantly reduce the maximum block size by limiting the size of data-heavy transactions that can fit into a single block. By increasing calldata costs from 4&#x2F;16 to 10&#x2F;40 gas per byte, for data-heavy transactions this EIP aims to reduce the possible EL payload size to approximately 0.72 MB (&lt;code&gt;30_000_000&#x2F;40&lt;&#x2F;code&gt;) without affecting the majority of users. Other adversarial block constructions can have a non-compressible EL payload size of approximately 1.26MiB.&lt;&#x2F;p&gt;
&lt;p&gt;Notably, regular users (e.g. sending ETH&#x2F;Tokens&#x2F;NFTs, engaging in DeFi, social media, restaking, bridging, etc.), who do not use calldata predominantly for DA, may remain unaffected.
The calldata cost for transactions involving significant EVM computation remains at 4&#x2F;16 gas per byte, so those transactions are unaffected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is a backwards incompatible gas repricing that requires a scheduled network upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;Wallet developers and node operators MUST update gas estimation handling to accommodate the new calldata cost rules. Specifically:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wallets&lt;&#x2F;strong&gt;: Wallets using &lt;code&gt;eth_estimateGas&lt;&#x2F;code&gt; MUST be updated to ensure that they correctly account for the &lt;code&gt;TOTAL_COST_FLOOR_PER_TOKEN&lt;&#x2F;code&gt; parameter. Failure to do so could result in underestimating gas, leading to failed transactions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Node Software&lt;&#x2F;strong&gt;: RPC methods such as &lt;code&gt;eth_estimateGas&lt;&#x2F;code&gt; MUST incorporate the updated formula for gas calculation. Node developers MUST ensure compatibility with the updated calldata pricing logic.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Users can maintain their usual workflows without modification, as wallet and RPC updates will handle these changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;As the maximum possible block size is reduced, no security concerns have been raised.&lt;&#x2F;p&gt;
&lt;p&gt;In some cases, it might seem advantageous to combine two transactions into one to reduce costs. For example, bundling a transaction that relies heavily on calldata but minimally on EVM resources with another that does the opposite. However, this is not a significant concern for several reasons:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;This type of bundling is already possible today. Merging multiple transactions can save the 21,000 gas cost for each additional transaction beyond the first, a feature explicitly supported in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Such bundling does not compromise the block size reduction objectives of this EIP.&lt;&#x2F;li&gt;
&lt;li&gt;In practice, transaction bundling is often impractical due to challenges such as trust and coordination requirements.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;These factors ensure that transaction bundling does not pose a significant issue.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hardfork Meta - Fusaka</title>
        <published>2024-02-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7607/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7607-fusaka-meta-eip/18439" />
        

        <id>https://wg-eips.ritovision.com/7607/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:7607"
            label="EIP-7607" />
        

        
        

        
        <summary type="html">EIPs included in the Fulu&#x2F;Osaka Ethereum network upgrade.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7607/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP lists the EIPs included in the Fulu&#x2F;Osaka network upgrade. It follows the Pectra upgrade, documented in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7600&#x2F;&quot;&gt;EIP-7600&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;included-eips&quot;&gt;Included EIPs&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;core-eips&quot;&gt;Core EIPs&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7594&#x2F;&quot;&gt;EIP-7594&lt;&#x2F;a&gt;: PeerDAS - Peer Data Availability Sampling&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7823&#x2F;&quot;&gt;EIP-7823&lt;&#x2F;a&gt;: Set upper bounds for MODEXP&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7825&#x2F;&quot;&gt;EIP-7825&lt;&#x2F;a&gt;: Transaction Gas Limit Cap&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7883&#x2F;&quot;&gt;EIP-7883&lt;&#x2F;a&gt;: ModExp Gas Cost Increase&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7917&#x2F;&quot;&gt;EIP-7917&lt;&#x2F;a&gt;: Deterministic proposer lookahead&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7918&#x2F;&quot;&gt;EIP-7918&lt;&#x2F;a&gt;: Blob base fee bounded by execution cost&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7934&#x2F;&quot;&gt;EIP-7934&lt;&#x2F;a&gt;: RLP Execution Block Size Limit&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7939&#x2F;&quot;&gt;EIP-7939&lt;&#x2F;a&gt;: Count leading zeros (CLZ) opcode&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7951&#x2F;&quot;&gt;EIP-7951&lt;&#x2F;a&gt;: Precompile for secp256r1 Curve Support&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;other-eips&quot;&gt;Other EIPs&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7892&#x2F;&quot;&gt;EIP-7892&lt;&#x2F;a&gt;: Blob Parameter Only Hardforks&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7642&#x2F;&quot;&gt;EIP-7642&lt;&#x2F;a&gt;: eth&#x2F;69 - Drop pre-merge fields
&lt;ul&gt;
&lt;li&gt;Client teams MUST support this EIP by the activation of the Fusaka network upgrade.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7910&#x2F;&quot;&gt;EIP-7910&lt;&#x2F;a&gt;: eth_config JSON-RPC Method
&lt;ul&gt;
&lt;li&gt;Client teams MUST support this JSON-RPC method by the activation of Fusaka network upgrade.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7935&#x2F;&quot;&gt;EIP-7935&lt;&#x2F;a&gt;: Set default gas limit to 60M&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Network Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;th&gt;Activation Time (UTC)&lt;&#x2F;th&gt;&lt;th&gt;Fork ID&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Holešky&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;165120&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1759308480&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-01 08:48:00&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x783def52&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sepolia&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;272640&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1760427360&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-14 07:36:00&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xe2ae4999&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hoodi&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;50688&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1761677592&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-28 18:53:12&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xe7e0e7ff&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;411392&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1764798551&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-12-03 21:49:11&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x5167e2a6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;blob-parameter-only-forks&quot;&gt;Blob Parameter Only Forks&lt;&#x2F;h3&gt;
&lt;p&gt;Blob Parameter Only (BPO) forks, defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7892&#x2F;&quot;&gt;EIP-7892&lt;&#x2F;a&gt;, are scheduled alongside Fusaka to raise blob capacity without additional protocol changes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bpo-1&quot;&gt;BPO 1&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Network Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;th&gt;Activation Time (UTC)&lt;&#x2F;th&gt;&lt;th&gt;Fork ID&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Holešky&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;166400&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1759800000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-07 01:20:00&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xa280a45c&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sepolia&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;274176&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1761017184&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-21 03:26:24&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x56078a1e&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hoodi&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;52480&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1762365720&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-11-05 18:02:00&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x3893353e&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;412672&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1765290071&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-12-09 14:21:11&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xcba2a1c0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;bpo-2&quot;&gt;BPO 2&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Network Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;th&gt;Activation Time (UTC)&lt;&#x2F;th&gt;&lt;th&gt;Fork ID&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Holešky&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;167936&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1760389824&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-13 21:10:24&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x9bc6cb31&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sepolia&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;275712&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1761607008&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-10-27 23:16:48&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x268956b6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hoodi&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;54016&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1762955544&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2025-11-12 13:52:24&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x23aa1351&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;419072&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1767747671&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2026-01-07 01:01:11&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x07c9462e&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP provides a global view of all changes included in the Fusaka network upgrade, as well as links to full specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hardfork Meta - Pectra</title>
        <published>2024-01-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7600/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7600-hardfork-meta-prague-electra/18205" />
        

        <id>https://wg-eips.ritovision.com/7600/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:7600"
            label="EIP-7600" />
        

        
        

        
        <summary type="html">EIPs included in the Prague&#x2F;Electra Ethereum network upgrade.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7600/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP lists the EIPs Included in the Prague&#x2F;Electra network upgrade. It follows the Dencun upgrade, documented in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7569&#x2F;&quot;&gt;EIP-7569&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;included-eips&quot;&gt;Included EIPs&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;core-eips&quot;&gt;Core EIPs&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;&quot;&gt;EIP-2537&lt;&#x2F;a&gt;: Precompile for BLS12-381 curve operations&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2935&#x2F;&quot;&gt;EIP-2935&lt;&#x2F;a&gt;: Save historical block hashes in state&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6110&#x2F;&quot;&gt;EIP-6110&lt;&#x2F;a&gt;: Supply validator deposits on chain&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;&quot;&gt;EIP-7002&lt;&#x2F;a&gt;: Execution layer triggerable exits&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7251&#x2F;&quot;&gt;EIP-7251&lt;&#x2F;a&gt;: Increase the MAX_EFFECTIVE_BALANCE&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7549&#x2F;&quot;&gt;EIP-7549&lt;&#x2F;a&gt;: Move committee index outside Attestation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7623&#x2F;&quot;&gt;EIP-7623&lt;&#x2F;a&gt;: Increase calldata cost&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt;: General purpose execution layer requests&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7691&#x2F;&quot;&gt;EIP-7691&lt;&#x2F;a&gt;: Blob throughput increase&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7702&#x2F;&quot;&gt;EIP-7702&lt;&#x2F;a&gt;: Set EOA account code&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;other-eips&quot;&gt;Other EIPs&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7840&#x2F;&quot;&gt;EIP-7840&lt;&#x2F;a&gt;: Add blob schedule to EL config files (Informational)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7642&#x2F;&quot;&gt;EIP-7642&lt;&#x2F;a&gt;: eth&#x2F;69 - Drop pre-merge fields (Networking)
&lt;ul&gt;
&lt;li&gt;While not necessary for the Pectra network upgrade, client teams MAY support EIP-7642 by the upgrade&#x27;s activation and MUST support it by the next network upgrade.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;full-specifications&quot;&gt;Full Specifications&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;consensus-layer&quot;&gt;Consensus Layer&lt;&#x2F;h4&gt;
&lt;p&gt;EIP-6110, EIP-7002 EIP-7251, EIP-7549, EIP-7685 and EIP-7691 require changes to Ethereum&#x27;s consensus layer. While the EIPs present an overview of these changes, the full specifications can be found in the &lt;code&gt;specs&#x2F;electra&lt;&#x2F;code&gt; and &lt;code&gt;specs&#x2F;_features&lt;&#x2F;code&gt; directories of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;execution-layer&quot;&gt;Execution Layer&lt;&#x2F;h4&gt;
&lt;p&gt;EIP-2537, EIP-2935, EIP-6110, EIP-7002, EIP-7623, EIP-7685, EIP-7702 and EIP-7840 require changes to Ethereum&#x27;s execution layer. The EIPs fully specify those changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Network Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Holešky&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;115968&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1740434112&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sepolia&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;222464&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1741159776&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hoodi&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2048&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1742999832&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;364032&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1746612311&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP provides a global view of all changes included in the Prague&#x2F;Electra network upgrade, as well as links to the full specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>PeerDAS - Peer Data Availability Sampling</title>
        <published>2024-01-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	<author>
		<name>Francesco D&#x27;Amato</name><uri>https://github.com/fradamt</uri>
	</author>
	
	<author>
		<name>Hsiao-Wei Wang</name><uri>https://github.com/hwwhww</uri>
	</author>
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7594/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7594-peerdas-peer-data-availability-sampling/18215" />
        

        <id>https://wg-eips.ritovision.com/7594/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7594"
            label="EIP-7594" />
        

        
        

        
        <summary type="html">Introducing simple DAS utilizing gossip distribution and peer requests</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7594/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;PeerDAS (Peer Data Availability Sampling) is a networking protocol that allows nodes to perform data availability sampling (DAS) to ensure that blob data has been made available while downloading only a subset of the data. PeerDAS utilizes gossip for distribution, discovery for finding peers of particular data custody, and peer requests for sampling.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;DAS is a method of scaling data availability beyond the levels of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; by not requiring all nodes to download all data while still ensuring that all of the data has been made available.&lt;&#x2F;p&gt;
&lt;p&gt;Providing additional data availability helps bring scale to Ethereum users in the context of layer 2 systems called &quot;roll-ups&quot; whose dominant bottleneck is layer 1 data availability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We extend the blobs introduced in EIP-4844 using a one-dimensional erasure coding extension. Each row consists of the blob data combined with its erasure code. It is subdivided into cells, which are the smallest units that can be authenticated with their respective blob&#x27;s KZG commitments. Each column, associated with a specific gossip subnet, consists of the cells from all rows for a specific index. Each node is responsible for maintaining a deterministic set of column subnets and custodying their data as a function of their node ID.&lt;&#x2F;p&gt;
&lt;p&gt;Nodes find and maintain a diverse peer set and sample columns from their peers to perform DAS every slot.&lt;&#x2F;p&gt;
&lt;p&gt;A node can reconstruct the entire data matrix if it acquires at least 50% of all the columns. If a node has less than 50%, it can request the necessary columns from its peer nodes.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, a limit of 6 blobs per transaction is introduced. Clients MUST enforce this limit when validating blob transactions at submission time, when received from the network, and during block production and processing.&lt;&#x2F;p&gt;
&lt;p&gt;The detailed specifications are on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;9d377fd53d029536e57cfda1a4d2c700c59f86bf&#x2F;specs&#x2F;fulu&#x2F;&quot;&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;networking&quot;&gt;Networking&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP introduces cell KZG proofs, which are used to prove that a KZG commitment opens to a cell at the given index. This allows downloading only specific cells from a blob, while still ensuring data integrity with respect to the corresponding KZG commitment, and is therefore a key component of data availability sampling. However, computing the cell proofs for a blob is an expensive operation, which a block producer would have to repeat for many blobs. Since proof verification is much cheaper than proof computation, and the proof size is negligible compared to cell size, we instead require blob transaction senders to compute the proofs themselves and include them in the EIP-4844 transaction pool wrapper for blob transactions.&lt;&#x2F;p&gt;
&lt;p&gt;To this end, during transaction gossip responses (&lt;code&gt;PooledTransactions&lt;&#x2F;code&gt;), the wrapper is modified to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp([tx_payload_body, wrapper_version, blobs, commitments, cell_proofs])&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;cell_proofs = [cell_proof_0, cell_proof_1, ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;tx_payload_body&lt;&#x2F;code&gt;, &lt;code&gt;blobs&lt;&#x2F;code&gt; and &lt;code&gt;commitments&lt;&#x2F;code&gt; are as in EIP-4844, while the &lt;code&gt;proofs&lt;&#x2F;code&gt; field is replaced by &lt;code&gt;cell_proofs&lt;&#x2F;code&gt;, and a &lt;code&gt;wrapper_version&lt;&#x2F;code&gt; is added. These are defined as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wrapper_version&lt;&#x2F;code&gt; - one byte indicating which version of the wrapper is used. For the current version, it is set to &lt;strong&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cell_proofs&lt;&#x2F;code&gt; - list of cell proofs for all &lt;code&gt;blobs&lt;&#x2F;code&gt;, including the proofs for the extension indices, for a total of &lt;code&gt;CELLS_PER_EXT_BLOB&lt;&#x2F;code&gt; proofs per blob (&lt;code&gt;CELLS_PER_EXT_BLOB&lt;&#x2F;code&gt; is the number of cells for an extended blob, defined &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;9d377fd53d029536e57cfda1a4d2c700c59f86bf&#x2F;specs&#x2F;fulu&#x2F;polynomial-commitments-sampling.md#cells&quot;&gt;in the consensus specs&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that, while &lt;code&gt;cell_proofs&lt;&#x2F;code&gt; contain the proofs for all cells, including the extension cells, the blobs themselves are sent without being extended (&lt;code&gt;CELLS_PER_EXT_BLOB &#x2F; 2&lt;&#x2F;code&gt; cells per blob). This is to avoid sending redundant data, which can quickly be computed by the receiving node.
In other words, &lt;code&gt;cell_proofs[i * CELLS_PER_EXT_BLOB + j]&lt;&#x2F;code&gt; is the proof for cell &lt;code&gt;j&lt;&#x2F;code&gt; of &lt;code&gt;compute_cells(blobs[i])&lt;&#x2F;code&gt;, where &lt;code&gt;compute_cells(blob)&lt;&#x2F;code&gt; outputs all cells of &lt;code&gt;blob&lt;&#x2F;code&gt;, including the extension cells.&lt;&#x2F;p&gt;
&lt;p&gt;The node MUST validate &lt;code&gt;tx_payload_body&lt;&#x2F;code&gt; and verify the wrapped data against it. To do so, ensure that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There are an equal number of &lt;code&gt;tx_payload_body.blob_versioned_hashes&lt;&#x2F;code&gt;, &lt;code&gt;blobs&lt;&#x2F;code&gt; and &lt;code&gt;commitments&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cell_proofs&lt;&#x2F;code&gt; contains exactly &lt;code&gt;CELLS_PER_EXT_BLOB * len(blobs)&lt;&#x2F;code&gt; cell proofs&lt;&#x2F;li&gt;
&lt;li&gt;The KZG &lt;code&gt;commitments&lt;&#x2F;code&gt; hash to the versioned hashes, i.e. &lt;code&gt;kzg_to_versioned_hash(commitments[i]) == tx_payload_body.blob_versioned_hashes[i]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The KZG &lt;code&gt;commitments&lt;&#x2F;code&gt; match the corresponding &lt;code&gt;blobs&lt;&#x2F;code&gt; and &lt;code&gt;cell_proofs&lt;&#x2F;code&gt;. This requires computing the extension cells for all &lt;code&gt;blobs&lt;&#x2F;code&gt; (e.g. via &lt;code&gt;compute_cells&lt;&#x2F;code&gt;), and verifying all &lt;code&gt;cell_proofs&lt;&#x2F;code&gt;. (Note: all cell proofs can be batch verified at once, e.g. via &lt;code&gt;verify_cell_kzg_proof_batch&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-use-das-to-scale-the-da-layer&quot;&gt;Why use DAS to scale the DA layer?&lt;&#x2F;h3&gt;
&lt;p&gt;PeerDAS is a DAS scheme that requires nodes to only download a small constant fraction of the data to satisfy a local availability check. With the current parameters, this is 1&#x2F;8 of the total data (i.e. blobs in a block), which can in the future be decreased to 1&#x2F;16 or even 1&#x2F;32 by reducing the size of samples (increasing the number of columns). In this way, PeerDAS allows for securely scaling the blob throughput of the network without compromising decentralization, i.e., without increasing node&#x27;s bandwidth and storage requirements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-does-peer-sampling-provide&quot;&gt;What does peer sampling provide?&lt;&#x2F;h3&gt;
&lt;p&gt;PeerDAS takes the set of peers of a node on the network as a primitive to build a DAS scheme around. A focus on peers allows for redundancy in the mechanism (as a node generally has many peers, and peer count can also be cheaply increased) which both helps with theoretical security as detailed in the &quot;Security Considerations&quot; section, but also practical security of the implementation (e.g. if a single peer fails, a node can likely use another peer for the same sampling task).&lt;&#x2F;p&gt;
&lt;p&gt;PeerDAS also has the nice property that any given node may voluntarily custody more of the data than the bare minimum which increases the performance of the mechanism. Alternative schemes do not readily support this &quot;transparent&quot; scaling property.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-are-these-parameters-chosen&quot;&gt;Why are these parameters chosen?&lt;&#x2F;h3&gt;
&lt;p&gt;The parameters of PeerDAS given in the specs support network security while keeping node requirements sufficiently low. See the security argument below for further details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-do-validators-have-an-additional-custody-requirement-beyond-full-nodes&quot;&gt;Why do validators have an additional custody requirement beyond full nodes?&lt;&#x2F;h3&gt;
&lt;p&gt;Validators are assumed to have marginally higher requirements to participate on the network. PeerDAS introduces a custody requirement that scales with the validator count so that nodes with more resources can contribute to a more stable backbone that makes the global network more robust.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;column-sampling-vs-row-sampling&quot;&gt;Column sampling vs row sampling&lt;&#x2F;h3&gt;
&lt;p&gt;PeerDAS defines a sample as a &quot;column&quot; which is a cross-section across &lt;em&gt;all&lt;&#x2F;em&gt; blobs, rather than a &quot;row&quot; which would be a full blob.
The sampling scheme could be defined over rows but then any reconstruction strategy would need to work over &quot;extension&quot; blobs that do not a priori exist on the network.
Reconstruction becomes much more tractable by working over columns as nodes can be assumed to have much more of the complete data by default (e.g. because most&#x2F;all of the blobs are in the public mempool).&lt;&#x2F;p&gt;
&lt;p&gt;Another benefit is that sampling over rows requires &lt;em&gt;column&lt;&#x2F;em&gt; extensions which would have to be done at the time of block construction, i.e. on the &quot;critical path&quot;. Sampling over columns requires row extensions which can be done in advance (not on the critical path), and moreover proof computation can be outsourced to senders of blob transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is fully backwards compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Refer to the consensus and execution spec tests for testing of this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The primary failure mode of a DAS scheme is a &quot;data withholding&quot; attack, where a block producer attempts to convince the network some data is available even when the block producer fails to provide the associated data.
PeerDAS resolves withholding attacks by implementing a (pseudo)randomized sampling scheme that decreases the probability of a successful attack as the size of the network grows for a sublinear amount of data that must be downloaded.&lt;&#x2F;p&gt;
&lt;p&gt;This intuition can be formalized as follows:&lt;&#x2F;p&gt;
&lt;p&gt;Letting &lt;code&gt;n&lt;&#x2F;code&gt; be the total number of sampling nodes (i.e. the size of the network), &lt;code&gt;m&lt;&#x2F;code&gt; be the total number of samples possible (cf. &lt;code&gt;NUMBER_OF_CUSTODY_GROUPS&lt;&#x2F;code&gt; in the specs) and &lt;code&gt;k&lt;&#x2F;code&gt; be the minimum number of samples that a node must download (cf. &lt;code&gt;SAMPLES_PER_SLOT&lt;&#x2F;code&gt; in the specs), we have the following bound for the probability of convincing a fraction $\epsilon$ of the nodes that some data is available when it is withheld:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7594&#x2F;.&#x2F;assets&#x2F;withholding-probability.svg&quot; alt=&quot;withholding-probability&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first term is the number of possible ways to choose a subset of $n\epsilon$ nodes whose sampling queries should be satisfied (i.e. the nodes to be tricked).
The second term is the number of ways to choose a maximally large subset of samples to be made available to satisfy the sampling queries of the $n\epsilon$ nodes without allowing reconstruction of the full data.
Finally, for any such choices, the third term is the probability of success, i.e. the probability that the sampling queries of all chosen $n\epsilon$ nodes are satisfied by the chosen subset up to the reconstruction threshold.&lt;&#x2F;p&gt;
&lt;p&gt;For mainnet parameters given in the specs and assuming 10,000 nodes on the network, we can compute upper bounds of attack success for varying $\epsilon$:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: center&quot;&gt;$\epsilon$&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;$n\epsilon$ (target nodes)&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Upper bound on $\mathbb{P}$&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0.01&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;100&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;$1$&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0.02&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;200&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;$10^{-20.04}$&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0.03&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;300&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;$10^{-101.55}$&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0.04&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;400&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;$10^{-198.24}$&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0.05&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;500&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;$10^{-306.34}$&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The table shows that the chances of a successful attack quickly drop to a negligible amount and so PeerDAS is considered secure to withholding attacks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Expirable NFTs and SBTs</title>
        <published>2024-01-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>sirawt</name><uri>https://github.com/MASDXI</uri>
	</author>
	
	<author>
		<name>ADISAKBOONMARK</name><uri>https://github.com/ADISAKBOONMARK</uri>
	</author>
	
	<author>
		<name>parametprame</name><uri>https://github.com/parametprame</uri>
	</author>
	
	<author>
		<name>Nacharoen</name><uri>https://github.com/najaroen</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7858/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7858-expirable-nft-sbt/22406" />
        

        <id>https://wg-eips.ritovision.com/7858/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7858"
            label="ERC-7858" />
        

        
        

        
        <summary type="html">Non-fungible (NFT) and soulbound (SBT) tokens with expiration, supporting time-limited use cases.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7858/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduces an extension for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; Non-Fungible Tokens (NFTs) and Soulbound Tokens (SBTs) that adds an expiration mechanism, allowing tokens to become invalid after a predefined period. This additional layer of functionality ensures that the expiration mechanism does not interfere with existing NFTs or SBTs, preserving transferability for NFTs and compatibility with current DApps such as NFT Marketplace. Expiration can be defined using either block height or timestamp, offering flexibility for various use cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Before this EIP, NFTs and SBTs implemented expiration mechanisms via custom mappings. However, this approach presents challenges, such as: inconsistent integration with other smart contracts, and the custom &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; implementations might misbehave when used in NFT marketplaces. This EIP addresses these issues by providing a built-in expiration mechanism and interfaces that are compatible with existing infrastructure. It supports both per-token and epoch-based expiry, allowing developers to choose the appropriate expiry type for their use cases, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Access and Authentication
&lt;ul&gt;
&lt;li&gt;Authentication for Identity and Access Management (IAM)&lt;&#x2F;li&gt;
&lt;li&gt;Membership for Membership Management System (MMS)&lt;&#x2F;li&gt;
&lt;li&gt;Ticket and Press for Meetings, Incentive Travel, Conventions, and Exhibitions (MICE) when using with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2135&#x2F;&quot;&gt;ERC-2135&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7578&#x2F;&quot;&gt;ERC-7578&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Subscription-based access for digital platforms.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Digital Certifications, Contracts, Copyrights, Documents, Licenses, Policies, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Loyalty Program voucher or coupon&lt;&#x2F;li&gt;
&lt;li&gt;Governance and Voting Rights&lt;&#x2F;li&gt;
&lt;li&gt;Financial Product
&lt;ul&gt;
&lt;li&gt;Bonds, Loans, Hedge, and Options Contract&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rental
&lt;ul&gt;
&lt;li&gt;Real Estate Unit, Digital Access, DePIN, etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Compatible implementations MUST implement the &lt;code&gt;IERC7858&lt;&#x2F;code&gt; interface and MUST inherit from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&#x27;s interface. All functions defined in the interface MUST be present and all function behavior MUST meet the interface specification requirements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7858: Expirable NFTs and SBTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unique&#x2F;granular expiry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; import &amp;quot;.&#x2F;IERC721.sol&amp;quot;;&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is `0x3ebdfa31`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7858&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;is IERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EXPIRY_TYPE&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        BLOCKS_BASED&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block.number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        TIME_BASED&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block.timestamp&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the expiration date of a token is set or updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the token ERC721 `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; startTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The start time of the token (block number or timestamp based on `expiryType`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; endTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The end time of the token (block number or timestamp based on `expiryType`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenExpiryUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; startTime&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; endTime&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the type of the expiry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; EXPIRY_TYPE&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Enum value indicating the unit of an expiry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; expiryType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;EXPIRY_TYPE&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a specific token is expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier representing the `tokenId` (ERC721).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the token is expired, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTokenExpired&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; return depends on the type `block.timestamp` or `block.number`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; {ERC-5007} return in uint64 MAY not suitable for `block.number` based.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; startTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; endTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;behavior-specification&quot;&gt;Behavior Specification&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt; that inherited from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; MUST return all tokens even if expired; they still exist but are unusable due to the limitation of tracking expired token on-chain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For NFTs &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, and &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; MUST allow transferring tokens even if they expired. This ensures that expired tokens remain transferable and tradable, preserving compatibility with existing applications already deployed. However, expired tokens MUST be considered invalid and unusable in contracts that check for token validity.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;expiryType&lt;&#x2F;code&gt; MUST return the type of expiry used by the contract, which can be either &lt;code&gt;BLOCK&lt;&#x2F;code&gt; or &lt;code&gt;TIME&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;isTokenExpired&lt;&#x2F;code&gt; is used for retrieving the status of the given &lt;code&gt;tokenId&lt;&#x2F;code&gt;; the function MUST return &lt;code&gt;true&lt;&#x2F;code&gt; if the token is expired and MUST revert if the &lt;code&gt;tokenId&lt;&#x2F;code&gt; does not exist. Implementations that use custom errors SHOULD revert with &lt;code&gt;ERC721NonexistentToken&lt;&#x2F;code&gt; following the relevant &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;&quot;&gt;ERC-6093&lt;&#x2F;a&gt; and implementations using Solidity version below &lt;code&gt;v0.8.4&lt;&#x2F;code&gt; or those preferring to use revert with string error SHOULD revert with &lt;code&gt;NonexistToken&lt;&#x2F;code&gt;. If the &lt;code&gt;tokenId&lt;&#x2F;code&gt; exists and is not expired, the function MUST return &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;startTime&lt;&#x2F;code&gt; and &lt;code&gt;endTime&lt;&#x2F;code&gt; of &lt;code&gt;tokenId&lt;&#x2F;code&gt;, can be &lt;code&gt;block.number&lt;&#x2F;code&gt; or &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; depending on &lt;code&gt;expiryType&lt;&#x2F;code&gt;. The &lt;code&gt;startTime&lt;&#x2F;code&gt; MUST be less than or equal to &lt;code&gt;endTime&lt;&#x2F;code&gt; and &lt;code&gt;startTime&lt;&#x2F;code&gt; SHOULD be strictly less than &lt;code&gt;endTime&lt;&#x2F;code&gt; except when both are set to &lt;code&gt;0&lt;&#x2F;code&gt;. A &lt;code&gt;startTime&lt;&#x2F;code&gt; and &lt;code&gt;endTime&lt;&#x2F;code&gt; of &lt;code&gt;0&lt;&#x2F;code&gt; indicates that the &lt;code&gt;tokenId&lt;&#x2F;code&gt; has no expiration. Tokens with a non-zero &lt;code&gt;startTime&lt;&#x2F;code&gt; and a zero &lt;code&gt;endTime&lt;&#x2F;code&gt; are also considered to have no expiration. If the &lt;code&gt;tokenId&lt;&#x2F;code&gt; does not exist, this function MUST revert in the same way as &lt;code&gt;isTokenExpired&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The interface ID for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; for &lt;code&gt;IERC7858&lt;&#x2F;code&gt; is &lt;code&gt;0x3ebdfa31&lt;&#x2F;code&gt;, and for &lt;code&gt;IERC7858Epoch&lt;&#x2F;code&gt; it is &lt;code&gt;0xec7ffd66&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TokenExpiryUpdated&lt;&#x2F;code&gt; MUST be emitted when the token is minted or when its expiration details (&lt;code&gt;startTime&lt;&#x2F;code&gt; or &lt;code&gt;endTime&lt;&#x2F;code&gt;) are updated.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;extension-interface&quot;&gt;Extension Interface&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Epochs&lt;&#x2F;strong&gt; represent a specific period or block range during which certain tokens are valid borrowing concepts from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7818&#x2F;&quot;&gt;ERC-7818&lt;&#x2F;a&gt;, tokens are grouped under an &lt;code&gt;epoch&lt;&#x2F;code&gt; and share the same &lt;code&gt;validityDuration&lt;&#x2F;code&gt;. For implementations that require epoch-based expiration management, the &lt;code&gt;IERC7858Epoch&lt;&#x2F;code&gt; extension interface MUST be implemented alongside the base &lt;code&gt;IERC7858&lt;&#x2F;code&gt; interface, and all functions and behaviors MUST meet both &lt;code&gt;IERC7858&lt;&#x2F;code&gt; and &lt;code&gt;IERC7858Epoch&lt;&#x2F;code&gt; interface specification requirements.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7858: Expirable NFTs and SBTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; epoch expiry extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; import &amp;quot;.&#x2F;IERC7858.sol&amp;quot;;&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is `0xec7ffd66`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7858Epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC7858 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the current epoch of the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The current epoch of the token contract,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * often used for determining active&#x2F;expired states.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; currentEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the duration of a single epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The duration of a single epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unit of the epoch length is determined by the `validityPeriodType` function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; epochLength&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a specific `epoch` is expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch` to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the token is expired, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Implementing contracts &amp;quot;MUST&amp;quot; define and document the logic for determining expiration,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * typically by comparing the latest epoch with the given `epoch` value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * based on the `EXPIRY_TYPE` measurement (e.g., block count or time duration).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isEpochExpired&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the balance of unexpired tokens owned by an account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of unexpired tokens owned by an account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unexpiredBalanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the balance of a specific `epoch` owned by an account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `epoch for which the balance is checked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The balance of the specified `epoch`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;MUST&amp;quot; return 0 if the specified `epoch` is expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unexpiredBalanceOfAtEpoch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the validity duration of each token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The validity duration of each token in `epoch` unit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validityDuration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;extension-behavior-specification&quot;&gt;Extension Behavior Specification&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unexpiredBalanceOfAtEpoch&lt;&#x2F;code&gt; MUST return the count of usable (unexpired) tokens held by an account from the specified &lt;code&gt;epoch&lt;&#x2F;code&gt;. If the specified &lt;code&gt;epoch&lt;&#x2F;code&gt; is expired, this function MUST return &lt;code&gt;0&lt;&#x2F;code&gt;. For example, if epoch &lt;code&gt;5&lt;&#x2F;code&gt; has expired, calling &lt;code&gt;unexpiredBalanceOfAtEpoch(5, address)&lt;&#x2F;code&gt; returns &lt;code&gt;0&lt;&#x2F;code&gt; even if there were tokens previously held in that epoch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;unexpiredBalanceOf&lt;&#x2F;code&gt; MUST return total count of usable (unexpired) tokens owned by the account.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;currentEpoch&lt;&#x2F;code&gt; MUST return the current &lt;code&gt;epoch&lt;&#x2F;code&gt; of the contract.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;epochLength&lt;&#x2F;code&gt; MUST return duration between &lt;code&gt;epoch&lt;&#x2F;code&gt; in blocks or time in seconds.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;validityDuration&lt;&#x2F;code&gt; MUST return the validity duration of tokens in terms of &lt;code&gt;epoch&lt;&#x2F;code&gt; counts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;isEpochExpired&lt;&#x2F;code&gt; MUST return true if the given &lt;code&gt;epoch&lt;&#x2F;code&gt; is expired, otherwise &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;additional-potential-useful-function&quot;&gt;Additional Potential Useful Function&lt;&#x2F;h3&gt;
&lt;p&gt;These OPTIONAL functions provide additional functionality that developers MAY choose to implement based on their specific requirements and use cases.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;base-default&quot;&gt;Base (default)&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRemainingDurationBeforeTokenExpired&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getRemainingDurationBeforeTokenExpired&lt;&#x2F;code&gt; returns the remaining time or blocks before the given &lt;code&gt;tokenId&lt;&#x2F;code&gt; is expired.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;epoch-extension&quot;&gt;Epoch (extension)&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getEpochBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getEpochBalance&lt;&#x2F;code&gt; returns the amount of tokens stored in a given epoch, even if the epoch has expired.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getEpochInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getEpochInfo&lt;&#x2F;code&gt; returns both the start and end of the specified &lt;code&gt;epoch&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getNearestExpiryOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getNearestExpiryOf&lt;&#x2F;code&gt; returns the list of &lt;code&gt;tokenId&lt;&#x2F;code&gt; closest to expiration, along with an estimated expiration block number or timestamp based on &lt;code&gt;epochType&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRemainingDurationBeforeEpochChange&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getRemainingDurationBeforeEpochChange&lt;&#x2F;code&gt; returns the remaining time or blocks before the epoch change happens, based on the &lt;code&gt;epochType&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;first-do-no-harm&quot;&gt;First, do no harm&lt;&#x2F;h3&gt;
&lt;p&gt;Introducing expirability as an additional layer of functionality ensures it doesn’t interfere with existing use cases or applications. For non-SBT tokens, transferability remains intact, maintaining compatibility with current systems. Expired tokens are simply flagged as unusable during validity checks, treating expiration as an enhancement rather than a fundamental change.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;expiry-types&quot;&gt;Expiry Types&lt;&#x2F;h3&gt;
&lt;p&gt;Defining expiration by either block height (&lt;code&gt;block.number&lt;&#x2F;code&gt;) or block timestamp (&lt;code&gt;block.timestamp&lt;&#x2F;code&gt;) offers flexibility for various use cases. Block-based expiration suits applications that rely on network activity and require precise consistency, while time-based expiration is ideal for networks with variable block intervals.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5484&#x2F;&quot;&gt;ERC-5484&lt;&#x2F;a&gt; and other SBTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;You can find our reference implementation &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7858&#x2F;assets&#x2F;README&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;burn-and-re-mint&quot;&gt;Burn and Re-Mint&lt;&#x2F;h3&gt;
&lt;p&gt;Implementation should ensure that burning token and re-minting it with the same &lt;code&gt;tokenId&lt;&#x2F;code&gt; will not introduce an unauthorized renewal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unauthorized-update&quot;&gt;Unauthorized Update&lt;&#x2F;h3&gt;
&lt;p&gt;Implementation should ensure that only authorized can update &lt;code&gt;startTime&lt;&#x2F;code&gt; and &lt;code&gt;endTime&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blob Transactions Metadata JSON Schema</title>
        <published>2024-01-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin Fu</name><uri>https://github.com/gavfu</uri>
	</author>
	
	<author>
		<name>Leo Wang</name><uri>https://github.com/wanglie1986</uri>
	</author>
	
	<author>
		<name>Bova Chen</name><uri>https://github.com/appoipp</uri>
	</author>
	
	<author>
		<name>Aiden X</name><uri>https://github.com/4ever9</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7588/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc7588-attaching-metadata-to-blobs-carried-by-blob-transactions/17873" />
        

        <id>https://wg-eips.ritovision.com/7588/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7588"
            label="ERC-7588" />
        

        
        

        
        <summary type="html">Attaching metadata to blobs carried by blob transactions</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7588/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a standard for attaching metadata to blobs carried by blob transactions, as outlined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;. The metadata is represented as a JSON object adhering to a predefined schema, and its string representation is placed in the data field of the blob transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; defines a new type of transaction known as a “blob transaction.” These transactions contain a list of blobs along with their KZG commitments and proofs. Blob transactions serve as a mechanism for rollups to post their layer 2 transaction data to Ethereum layer 1.&lt;&#x2F;p&gt;
&lt;p&gt;While rollups typically manage their own posted blob transactions, third-party solutions (such as Portal Network and blobscan) may also index all blobs ever posted to Ethereum, and provide querying services for blobs. By attaching metadata to blobs, such as information about the originator, a description, or content type, we can significantly enhance the visibility and auditability of these data structures.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, decentralized storage applications may utilize blob transactions to post user data to Ethereum, sync and store the blobs off-chain for future retrieval. The inclusion of metadata opens up possibilities for novel applications, including inscriptions and other creative use cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;metadata-json-schema&quot;&gt;Metadata JSON Schema&lt;&#x2F;h3&gt;
&lt;p&gt;The metadata is represented as a JSON object adhering to the following JSON Schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Blobs Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;originator&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the originator of the carried blobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the contents of the blobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the MIME type of the blobs. The MIME type should be defined in RFC 2046 (https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2046)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;extras&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Dynamic extra information related to the blobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Metadata of the i&amp;#39;th blob. This is optional and overlays the upper level properties if provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the content of the i&amp;#39;th blob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the MIME type of the i&amp;#39;th blob. The MIME type should be defined in RFC 2046 (https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2046)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;extras&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Dynamic extra information related to the i&amp;#39;th blob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;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;For example, suppose Vitalik wants to send a blob transaction carrying two blobs explaining “data availability sampling.” He could include a paragraph of textual explanation in the first blob and an illustration image in the second blob. The corresponding metadata JSON object would look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;originator&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Vitalik Buterin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;An illustration of data availability sampling&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;text&#x2F;plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;This blob contains a description text of the illustration.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&#x2F;png&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;This blob contains the illustration image data in base64 format. It&amp;#39;s a RFC 2397 (https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2397) data URL.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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 complete blob transaction would include this metadata in the data field, along with other relevant fields:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blobVersionedHashes&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11155111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Supposing the blob transaction is posted to Sepolia&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip4844&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28236&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; String representation of the above metadata JSON object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerBlobGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1073677089&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1213388073&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxPriorityFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1165808679&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sidecars&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blob&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;commitment&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blob&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;commitment&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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;h3 id=&quot;blob-transaction-envelope&quot;&gt;Blob Transaction Envelope&lt;&#x2F;h3&gt;
&lt;p&gt;The blob transaction&#x27;s calldata (i.e., the data field) should be set to the string representation of the metadata JSON object, encoded in UTF-8.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;In the Ethereum ecosystem, various types of transactions exist, each serving different purposes. The usage of the data field within these transactions varies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Regular Funds Transfer Transactions&lt;&#x2F;strong&gt;:
In these transactions, the data field is typically not used, and users may optionally include arbitrary data.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Smart Contract Deployment Transactions&lt;&#x2F;strong&gt;:
For deploying smart contracts. The data field holds the contract bytecode and any encoded arguments required by the constructor.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Smart Contract Function Call Transactions&lt;&#x2F;strong&gt;:
When invoking smart contract functions, the data field contains the function call data, including the function signature and any necessary parameters.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Blob transactions are specifically designed for posting blobs, and normally, the data field remains unused. This EIP proposes a novel approach: utilizing the data field to attach metadata to the carried blobs. By doing so, we can enhance the auditability and usability of blob transactions.&lt;&#x2F;p&gt;
&lt;p&gt;However, it’s essential to note that there are scenarios where blob transactions may also need to call smart contract functions. Consider a decentralized storage application that employs a smart contract to track blob versioned hashes and metadata like MIME types. In such cases, users could submit a blob transaction containing blobs while simultaneously using the data field to invoke smart contract functions to store versioned hashes and MIME types of those blobs. It’s important to recognize that this EIP does not cover such specific use cases.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h1&gt;
&lt;p&gt;This EIP is backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;, as it does not modify the structure or functionality of blob transactions, but only adds an optional metadata field to them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce any new security risks or vulnerabilities, as the metadata is only an informational field that does not affect the execution or validity of blob transactions. However, users and applications should be aware of the following potential issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The metadata is not verified or enforced by the consensus layer, and therefore it may not be accurate or trustworthy. Users and applications should not rely on the metadata for critical or sensitive operations, and should always verify the contents and sources of the blobs themselves.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The metadata may contain malicious or harmful data, such as spam, phishing, malware, etc. Users and applications should not blindly trust or execute the metadata, and should always scan and sanitize the metadata before using it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The metadata may increase the gas cost of blob transactions, as more data is included in the data field. Users and applications should balance the benefits and costs of using the metadata, and should optimize the size and format of the metadata to reduce the gas cost.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Reserve Precompile Address Range for RIPs</title>
        <published>2023-12-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Carl Beekhuizen</name><uri>https://github.com/carlbeek</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7587/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-75xx-reserve-precompile-address-range-for-rips-l2s/17828" />
        

        <id>https://wg-eips.ritovision.com/7587/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:7587"
            label="EIP-7587" />
        

        
        

        
        <summary type="html">Reserve precompile address range for use by the RIP process</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7587/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP reserves precompile ranges to ensure there are no conflicts with those used by the Rollup Improvement Proposal (RIP) process.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As L2s begin to deploy RIPs, it is necessary to reserve an address range for use by the RIP process so as to ensure there are no conflicts between precompile addresses used by RIPs and EIPs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The address range between &lt;code&gt;0x0000000000000000000000000000000000000100&lt;&#x2F;code&gt; and &lt;code&gt;0x00000000000000000000000000000000000001ff&lt;&#x2F;code&gt; is reserved for use by the RIP process.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;By reserving an address range for RIPs, it allows the RIP process to maintain its own registry of precompiles that are not (necessarily) deployed on L1 mainnet, the EIP process is freed from having to maintain a registry of RIP precompiles while still having 255 addresses for its own use.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Nil.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multi-Asset ERC-4626 Vaults</title>
        <published>2023-12-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Jeroen Offerijns</name><uri>https://github.com/hieronx</uri>
	</author>
	
	<author>
		<name>Alina Sinelnikova</name><uri>https://github.com/ilinzweilin</uri>
	</author>
	
	<author>
		<name>Vikram Arun</name><uri>https://github.com/vikramarun</uri>
	</author>
	
	<author>
		<name>Joey Santoro</name><uri>https://github.com/joeysantoro</uri>
	</author>
	
	<author>
		<name>Farhaan Ali</name><uri>https://github.com/0xfarhaan</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7575/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7575-partial-and-extended-erc-4626-vaults/17274" />
        

        <id>https://wg-eips.ritovision.com/7575/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7575"
            label="ERC-7575" />
        

        
        

        
        <summary type="html">Extended ERC-4626 Interface enabling Multi-Asset Vaults</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7575/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard adapts &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; to support multiple assets or entry points for the same share token. This also enables Vaults which don&#x27;t have a true share token but rather convert between two arbitrary external tokens.&lt;&#x2F;p&gt;
&lt;p&gt;It adds a new &lt;code&gt;share&lt;&#x2F;code&gt; method to the Vault, to allow the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; dependency to be externalized.&lt;&#x2F;p&gt;
&lt;p&gt;It also adds Vault-to-Share lookup to the share token.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, it enforces &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; support for Vaults and the share token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;One missing use case that is not supported by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; is Vaults which have multiple assets or entry points such as liquidity provider (LP) Tokens. These are generally unwieldy or non-compliant due to the requirement of ERC-4626 to itself be an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions:&lt;&#x2F;h3&gt;
&lt;p&gt;The existing definitions from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; apply. In addition, this spec defines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-Asset Vaults: A Vault which has multiple assets&#x2F;entry points. The Multi-Asset Vault refers to the group of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; contracts with the entry points for a specific asset, linked to one common &lt;code&gt;share&lt;&#x2F;code&gt; token.&lt;&#x2F;li&gt;
&lt;li&gt;Pipe: A converter from one token to another (unidirectional or bidirectional)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;p&gt;All &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; Vaults MUST implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; excluding the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; methods and events.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;share&quot;&gt;share&lt;&#x2F;h4&gt;
&lt;p&gt;The address of the underlying &lt;code&gt;share&lt;&#x2F;code&gt; received on deposit into the Vault. MUST return an address of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; share representation of the Vault.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;share&lt;&#x2F;code&gt; MAY return the address of the Vault itself.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;share&lt;&#x2F;code&gt; returns an external token i.e. &lt;code&gt;share != address(this)&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;entry functions MUST increase the &lt;code&gt;share&lt;&#x2F;code&gt; balance of the &lt;code&gt;receiver&lt;&#x2F;code&gt; by the &lt;code&gt;shares&lt;&#x2F;code&gt; amount. i.e. &lt;code&gt;share.balanceOf(receiver) += shares&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;exit functions MUST decrease the &lt;code&gt;share&lt;&#x2F;code&gt; balance of the &lt;code&gt;owner&lt;&#x2F;code&gt; by the &lt;code&gt;shares&lt;&#x2F;code&gt; amount. i.e. &lt;code&gt;share.balanceOf(owner) -= shares&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;MUST &lt;em&gt;NOT&lt;&#x2F;em&gt; revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hare&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hareTokenAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;multi-asset-vaults&quot;&gt;Multi-Asset Vaults&lt;&#x2F;h3&gt;
&lt;p&gt;Multi-Asset Vaults share a single &lt;code&gt;share&lt;&#x2F;code&gt; token with multiple entry points denominated in different &lt;code&gt;asset&lt;&#x2F;code&gt; tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Multi-Asset Vaults MUST implement the &lt;code&gt;share&lt;&#x2F;code&gt; method on each entry point. The entry points SHOULD NOT be &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pipes&quot;&gt;Pipes&lt;&#x2F;h3&gt;
&lt;p&gt;Pipes convert between a single &lt;code&gt;asset&lt;&#x2F;code&gt; and &lt;code&gt;share&lt;&#x2F;code&gt; which are both &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens outside the Vault.&lt;&#x2F;p&gt;
&lt;p&gt;A Pipe MAY be either unidirectional or bidirectional.&lt;&#x2F;p&gt;
&lt;p&gt;A unidirectional Pipe SHOULD implement only the entry function(s) &lt;code&gt;deposit&lt;&#x2F;code&gt; and&#x2F;or &lt;code&gt;mint&lt;&#x2F;code&gt;, not &lt;code&gt;redeem&lt;&#x2F;code&gt; and&#x2F;or &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The entry points SHOULD lock or burn the &lt;code&gt;asset&lt;&#x2F;code&gt; from the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; and mint or transfer the &lt;code&gt;share&lt;&#x2F;code&gt; to the &lt;code&gt;receiver&lt;&#x2F;code&gt;. For bidirectional pipes, the exit points SHOULD lock or burn the &lt;code&gt;share&lt;&#x2F;code&gt; from the &lt;code&gt;owner&lt;&#x2F;code&gt; and mint or transfer the &lt;code&gt;asset&lt;&#x2F;code&gt; to the &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;share-to-vault-lookup&quot;&gt;Share-to-Vault lookup&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; implementation of &lt;code&gt;share&lt;&#x2F;code&gt; SHOULD implement a &lt;code&gt;vault&lt;&#x2F;code&gt; method, that returns the address of the Vault for a specific &lt;code&gt;asset&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD emit the &lt;code&gt;VaultUpdate&lt;&#x2F;code&gt; event when a Vault linked to the share changes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ault&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&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&gt;    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ault&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-165-support&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; support&lt;&#x2F;h3&gt;
&lt;p&gt;Vaults implementing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; MUST implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function. The Vault contract MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0x2f0a18c5&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;p&gt;
&lt;p&gt;The share contract SHOULD implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function. The share token MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0xf815c03d&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;vaultupdate&quot;&gt;VaultUpdate&lt;&#x2F;h4&gt;
&lt;p&gt;The Vault linked to the share has been updated.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; V&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;aultUpdate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ault&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is intentionally flexible to support both existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; Vaults easily by the introduction of a single new method, but also flexible to support new use cases by allowing separate share tokens.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ability-to-externalize-erc-20-dependency&quot;&gt;Ability to externalize &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; Dependency&lt;&#x2F;h3&gt;
&lt;p&gt;By allowing &lt;code&gt;share != address(this)&lt;&#x2F;code&gt;, the Vault can have an external contract managing the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; functionality of the Share. In the case of Multi-Asset, this avoids the confusion that might arise if each Vault itself were required to be an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, which could confuse integrators and front-ends.&lt;&#x2F;p&gt;
&lt;p&gt;This approach also enables the creation of new types of Vaults, such as Pipes, which facilitate the conversion between two external &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens. These Pipes could be unidirectional (i.e. only for assets to shares via deposit&#x2F;mint, or shares to assets via redeem&#x2F;withdraw) or bidirectional for both entry and exit flows.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;including-share-to-vault-lookup-optionally&quot;&gt;Including Share-to-Vault lookup optionally&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;vault&lt;&#x2F;code&gt; method is included to look up a Vault for a &lt;code&gt;share&lt;&#x2F;code&gt; by its &lt;code&gt;asset&lt;&#x2F;code&gt;, combined with the &lt;code&gt;VaultUpdate&lt;&#x2F;code&gt; event and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; support. This enables integrations to easily query Multi-Asset Vaults.&lt;&#x2F;p&gt;
&lt;p&gt;This is optional, to maintain backward compatibility with use cases where the &lt;code&gt;share&lt;&#x2F;code&gt; is an existing deployed contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; Vaults are not fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; because the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; functionality has been removed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure&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 class=&quot;z-storage z-type&quot;&gt;    contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Share&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; asset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateVault&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; asset&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vault_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;            vault&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;asset&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateVault&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;asset&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vault_&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xf815c03d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;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 class=&quot;z-storage z-type&quot;&gt;    contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenAVault&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7575&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; share &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Share&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; asset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TokenA&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC4626 implementation&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 class=&quot;z-storage z-type&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x2f0a18c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;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 class=&quot;z-storage z-type&quot;&gt;    contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenBVault&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7575&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; share &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Share&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; asset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TokenB&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC4626 implementation&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 class=&quot;z-storage z-type&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x2f0a18c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; non-compliant Vaults must take care with supporting a redeem flow where &lt;code&gt;owner&lt;&#x2F;code&gt; is not &lt;code&gt;msg.sender&lt;&#x2F;code&gt;, since the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; approval flow does not by itself work if the Vault and share are separate contracts. It can work by setting up the Vault as a Trusted Forwarder of the share token, using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2771&#x2F;&quot;&gt;ERC-2771&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hardfork Meta Backfill - Berlin to Shapella</title>
        <published>2023-12-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7568/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/hardfork-meta-backfill/16923" />
        

        <id>https://wg-eips.ritovision.com/7568/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7568"
            label="EIP-7568" />
        

        
        

        
        <summary type="html">Pointers to specifications used for the network upgrades from Berlin to Shapella.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7568/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Following Muir Glacier hard fork, Meta EIPs were abandoned in favor of other ways to track changes included in Ethereum network upgrades. This EIP aggregates the specifications for these upgrades, which themselves list the specific changes included. Specifically, it covers the Beacon Chain launch (Serenity Phase 0), Berlin, London, Altair, Arrow Glacier, Gray Glacier, The Merge (Paris + Bellatrix) and Shapella (Shanghai + Capella).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;For many years, Ethereum used Meta EIPs to document network upgrades. Recently, consensus has formed around using them again. This EIP aggregates the network upgrades who did not have Meta EIPs and links out to their specifications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The network upgrades below are listed in order of activation. Upgrades to Ethereum&#x27;s execution layer are marked &quot;[EL]&quot;, and those to Ethereum&#x27;s consensus layer are marked &quot;[CL]&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;beacon-chain-launch-serenity-phase-0-cl&quot;&gt;Beacon Chain Launch - Serenity Phase 0 [CL]&lt;&#x2F;h3&gt;
&lt;p&gt;The full specifications for the Beacon Chain at launch can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;579da6d2dc734b269dbf67aa1004b54bb9449784&#x2F;README.md#phase-0&quot;&gt;&lt;code&gt;v1.0.0&lt;&#x2F;code&gt; release of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;. Additionally, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;&quot;&gt;EIP-2982&lt;&#x2F;a&gt; provides context on the Beacon Chain design and rationale for its mainnet parametrization.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;berlin-el&quot;&gt;Berlin [EL]&lt;&#x2F;h3&gt;
&lt;p&gt;The set of EIPs included in Berlin were originally specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6953&#x2F;&quot;&gt;EIP-2070&lt;&#x2F;a&gt;, but then moved to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;berlin.md&quot;&gt;&lt;code&gt;berlin.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;london-el&quot;&gt;London [EL]&lt;&#x2F;h3&gt;
&lt;p&gt;The set of EIPs included in London are specified in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;london.md&quot;&gt;&lt;code&gt;london.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;altair-cl&quot;&gt;Altair [CL]&lt;&#x2F;h3&gt;
&lt;p&gt;The full specifications for the Altair network upgrade can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;67fd7979ffd705bd6b0b5c1aaa842a445cc74d9a&#x2F;README.md#altair&quot;&gt;&lt;code&gt;v1.1.0&lt;&#x2F;code&gt; release of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;arrow-glacier-el&quot;&gt;Arrow Glacier [EL]&lt;&#x2F;h3&gt;
&lt;p&gt;The set of EIPs included in Arrow Glacier are specified in the&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;arrow-glacier.md&quot;&gt;&lt;code&gt;arrow-glacier.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gray-glacier-el&quot;&gt;Gray Glacier [EL]&lt;&#x2F;h3&gt;
&lt;p&gt;The set of EIPs included in Gray Glacier are specified in the&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;gray-glacier.md&quot;&gt;&lt;code&gt;gray-glacier.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-merge&quot;&gt;The Merge&lt;&#x2F;h3&gt;
&lt;p&gt;The Merge was the first upgrade to require coordination between the execution and consensus layers. The consensus layer first activated the Bellatrix upgrade, which was followed by the activation of Paris on the execution layer.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bellatrix-cl&quot;&gt;Bellatrix [CL]&lt;&#x2F;h4&gt;
&lt;p&gt;The full specifications for the Bellatrix network upgrade can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;f8ae982c2fc7dbb03a3c95a638da4486310e09e9&#x2F;README.md#stable-specifications&quot;&gt;&lt;code&gt;v1.2.0&lt;&#x2F;code&gt; release of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;paris-el&quot;&gt;Paris [EL]&lt;&#x2F;h4&gt;
&lt;p&gt;The set of EIPs included in Paris are specified in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;paris.md&quot;&gt;&lt;code&gt;paris.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shapella&quot;&gt;Shapella&lt;&#x2F;h3&gt;
&lt;p&gt;The Shapella upgrade was the first upgrade to activate at the same time on both the execution and consensus layers. To enable this, the upgrade activation mechanism on the execution layer was changed to use timestamps instead of blocks. This is described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6953&#x2F;&quot;&gt;EIP-6953&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6122&#x2F;&quot;&gt;EIP-6122&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;shanghai-el&quot;&gt;Shanghai [EL]&lt;&#x2F;h4&gt;
&lt;p&gt;The set of EIPs included in Shanghai are specified in the&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-specs&#x2F;blob&#x2F;8dbde99b132ff8d8fcc9cfb015a9947ccc8b12d6&#x2F;network-upgrades&#x2F;mainnet-upgrades&#x2F;shanghai.md&quot;&gt;&lt;code&gt;shanghai.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; file of the &lt;code&gt;ethereum&#x2F;execution-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;capella-cl&quot;&gt;Capella [CL]&lt;&#x2F;h4&gt;
&lt;p&gt;The full specifications for the Capella network upgrade can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;01b53691dcc36d37a5ad8994b3a32d8de69fb1aa&#x2F;README.md#stable-specifications&quot;&gt;&lt;code&gt;v1.3.0&lt;&#x2F;code&gt; release of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The EIP repository is well known within the Ethereum community, and Meta EIPs have historically been useful to clearly list the EIPs included in a specific network upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;While the specification process for the execution and consensus layers differ, there is value in having a single, harmonized, list of EIPs included in each upgrade, and for the lists for both layers to be part of the same repository.&lt;&#x2F;p&gt;
&lt;p&gt;Re-introducing Hardfork Meta EIPs enables this, and allows for de-duplication in cases where an EIP affects both the execution and consensus layer of Ethereum. This EIP covers the upgrades which did not use a Hardfork Meta EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hardfork Meta - Dencun</title>
        <published>2023-12-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7569/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/dencun-hardfork-meta/16924" />
        

        <id>https://wg-eips.ritovision.com/7569/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7569"
            label="EIP-7569" />
        

        
        

        
        <summary type="html">EIPs included in the Deneb&#x2F;Cancun Ethereum network upgrade.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7569/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP lists the EIPs included in the Dencun network upgrade across both Ethereum&#x27;s execution and consensus layers. See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7568&#x2F;&quot;&gt;EIP-7568&lt;&#x2F;a&gt; for the specifications of past upgrades.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;included-eips&quot;&gt;Included EIPs&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1153&#x2F;&quot;&gt;EIP-1153&lt;&#x2F;a&gt;: Transient storage opcodes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt;: Beacon block root in the EVM&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;: Shard Blob Transactions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5656&#x2F;&quot;&gt;EIP-5656&lt;&#x2F;a&gt;: MCOPY - Memory copying instruction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6780&#x2F;&quot;&gt;EIP-6780&lt;&#x2F;a&gt;: SELFDESTRUCT only in same transaction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7044&#x2F;&quot;&gt;EIP-7044&lt;&#x2F;a&gt;: Perpetually Valid Signed Voluntary Exits&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7045&#x2F;&quot;&gt;EIP-7045&lt;&#x2F;a&gt;: Increase Max Attestation Inclusion Slot&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7514&#x2F;&quot;&gt;EIP-7514&lt;&#x2F;a&gt;: Add Max Epoch Churn Limit&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7516&#x2F;&quot;&gt;EIP-7516&lt;&#x2F;a&gt;: BLOBBASEFEE opcode&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;full-specifications&quot;&gt;Full Specifications&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;consensus-layer&quot;&gt;Consensus Layer&lt;&#x2F;h4&gt;
&lt;p&gt;EIPs 4788, 4844, 7044, 7045 and 7514 require changes to Ethereum&#x27;s consensus layer. These are specified in the &lt;code&gt;deneb&lt;&#x2F;code&gt; folder of the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;execution-layer&quot;&gt;Execution Layer&lt;&#x2F;h4&gt;
&lt;p&gt;EIPs 1153, 4788, 4844, 5656, 6780 and 7516 require changes to Ethereum&#x27;s execution layer. The EIPs fully specify the changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Network Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Goerli&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;231680&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1705473120&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sepolia&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;132608&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1706655072&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Holešky&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;29696&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1707305664&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;269568&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1710338135&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: rows in the table above will be filled as activation times are decided by client teams.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This Meta EIP provides a global view of all changes included in the Dencun network upgrade, as well as links to full specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Move committee index outside Attestation</title>
        <published>2023-11-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>dapplion</name><uri>https://github.com/dapplion</uri>
	</author>
	
	<author>
		<name>Mikhail Kalinin</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7549/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7549-move-committee-index-outside-attestation/16390" />
        

        <id>https://wg-eips.ritovision.com/7549/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7549"
            label="EIP-7549" />
        

        
        

        
        <summary type="html">Move committee index outside of the signed Attestation message</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7549/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Move the committee&#x27;s &lt;code&gt;index&lt;&#x2F;code&gt; field outside of the signed Attestation message to allow aggregation of equal consensus votes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal aims to make Casper FFG clients more efficient by reducing the average number of pairings needed to verify consensus rules. While all types of clients can benefit from this EIP, ZK circuits proving Casper FFG consensus will likely have the most impact.&lt;&#x2F;p&gt;
&lt;p&gt;On a beacon chain network with at least 262144 active indices, it&#x27;s necessary to verify a minimum of &lt;code&gt;ceil(32*64 * 2&#x2F;3) = 1366&lt;&#x2F;code&gt; attestations to reach a 2&#x2F;3 threshold. Participants cast two votes at once: LMD GHOST vote and Casper-FFG vote. However, the Attestation message contains three elements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;LMD GHOST vote &lt;code&gt;(beacon_block_root, slot)&lt;&#x2F;code&gt;. Note: includes slot in the event (block, slot) voting is adopted.&lt;&#x2F;li&gt;
&lt;li&gt;FFG vote &lt;code&gt;(source, target)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Committee index &lt;code&gt;(index)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Signing over the 3rd item causes tuples of equal votes to produce different signing roots. If the committee index is moved outside of the Attestation message, the minimum number of attestations to verify to reach a 2&#x2F;3 threshold is reduced to &lt;code&gt;ceil(32 * 2&#x2F;3) = 22&lt;&#x2F;code&gt; (a factor of 62).&lt;&#x2F;p&gt;
&lt;p&gt;On-chain attestations can now be packed more space-efficiently into beacon blocks. This proposal allows for up to 8 slots worth of votes in a block, compared to 2 today. In other words, a chain with only 1&#x2F;8 online proposers can still potentially include all votes on-chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution layer&lt;&#x2F;h3&gt;
&lt;p&gt;This requires no changes to the Execution Layer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;index&lt;&#x2F;code&gt; field from &lt;code&gt;AttestationData&lt;&#x2F;code&gt; to a fixed value of zero&lt;&#x2F;li&gt;
&lt;li&gt;Move committee indexing data to the outer &lt;code&gt;Attestation&lt;&#x2F;code&gt; container with &lt;code&gt;committee_bits&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Increase the capacity of &lt;code&gt;aggregation_bits&lt;&#x2F;code&gt; to all committees in a slot&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The full specification of the proposed change can be found in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;2c1f677187e6534aec77057a7d1cc746a40d3630&#x2F;specs&#x2F;electra&#x2F;beacon-chain.md&quot;&gt;&lt;code&gt;&#x2F;specs&#x2F;electra&#x2F;beacon-chain.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;deprecation-strategy&quot;&gt;Deprecation strategy&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;index&lt;&#x2F;code&gt; field in &lt;code&gt;AttestationData&lt;&#x2F;code&gt; can be deprecated by:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Removing the field&lt;&#x2F;li&gt;
&lt;li&gt;Preserving the field and setting it to zero&lt;&#x2F;li&gt;
&lt;li&gt;Changing the field type to Optional (from EIP-7495 StableContainer)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This EIP chooses the second option to not complicate the inclusion of &lt;code&gt;AttesterSlashing&lt;&#x2F;code&gt; objects. While the &lt;code&gt;Attestation&lt;&#x2F;code&gt; container changes, &lt;code&gt;AttesterSlashing&lt;&#x2F;code&gt; includes indexed attestations without committee data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;max-attestations-value&quot;&gt;&lt;code&gt;MAX_ATTESTATIONS&lt;&#x2F;code&gt; value&lt;&#x2F;h3&gt;
&lt;p&gt;The maximum size of an attestation increases, with a bitfield 64 times larger on networks with maxed committees. &lt;code&gt;MAX_ATTESTATIONS&lt;&#x2F;code&gt; value is reduced to limit the beacon block size while still increasing the total capacity of votes. A value of 8 increases the voting capacity by 4 while having the same attestation space size with a network of 1.2M active indices.
Read the details &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7549&#x2F;assets&#x2F;complexity_analysis&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;max-attester-slashings-value&quot;&gt;&lt;code&gt;MAX_ATTESTER_SLASHINGS&lt;&#x2F;code&gt; value&lt;&#x2F;h3&gt;
&lt;p&gt;On-chain &lt;code&gt;AttesterSlashing&lt;&#x2F;code&gt; includes a list of participants&#x27; indices. With this EIP, the worst-case size increases by 64 times, resulting in an uncompressed size of 488 KB per &lt;code&gt;AttesterSlashing&lt;&#x2F;code&gt; in a network of 1M validators. Snappy compression reduces it to 320 KB, which is still significant. To bound the maximum size of the block, this proposal reduces &lt;code&gt;MAX_ATTESTER_SLASHINGS&lt;&#x2F;code&gt; from 2 to 1, the minimum value.
Read the details &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7549&#x2F;assets&#x2F;complexity_analysis&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-bitvector-for-committee-bits&quot;&gt;Using &lt;code&gt;Bitvector&lt;&#x2F;code&gt; for &lt;code&gt;committee_bits&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;committee_bits&lt;&#x2F;code&gt; sequence has a variable length with the max size &lt;code&gt;MAX_COMMITTEES_PER_SLOT = 64&lt;&#x2F;code&gt;. Encoding of the &lt;code&gt;Bitlist&lt;&#x2F;code&gt; includes its actual length, which doubles the size of the &lt;code&gt;committee_bits&lt;&#x2F;code&gt; compared to the &lt;code&gt;Bitvector&lt;&#x2F;code&gt; type. Beacon chain state transition ensures correctness of the &lt;code&gt;committee_bits&lt;&#x2F;code&gt; when the effective number of committees in a slot is less than its max value.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backward-incompatible changes to the block validation rule set on the consensus layer and must be accompanied by a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;first-block-after-the-fork&quot;&gt;First block after the fork&lt;&#x2F;h3&gt;
&lt;p&gt;Because the on-chain &lt;code&gt;Attestation&lt;&#x2F;code&gt; container changes, attestations from the prior fork can&#x27;t be included in post-Electra blocks. Therefore, the first block after the fork may have zero attestations. LMD votes can still be applied to fork-choice via &lt;code&gt;on_attestation&lt;&#x2F;code&gt; handler, so there will be only a 1&#x2F;32 loss of FFG votes. Attesters assigned to the last slot of the fork will incur one epoch worth of offline penalties. One possible mitigation is to change the Electra block body type to allow including attestations from both forks. However, the mitigation increases complexity for little gain, so this proposal chooses not to address the issue.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mutation-over-gossip&quot;&gt;Mutation over gossip&lt;&#x2F;h3&gt;
&lt;p&gt;Moving the &lt;code&gt;index&lt;&#x2F;code&gt; field outside of the signed message allows malicious mutation only on the p2p gossip topic &lt;code&gt;beacon_attestation_${subnet_id}&lt;&#x2F;code&gt;. Everywhere else, the &lt;code&gt;Attestation&lt;&#x2F;code&gt; message is wrapped with an outer signature that prevents mutation.&lt;&#x2F;p&gt;
&lt;p&gt;Gossip verification rules for the &lt;code&gt;beacon_attestation_${subnet_id}&lt;&#x2F;code&gt; topic include:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;[REJECT] The attester is a member of the committee -- i.e., &lt;code&gt;attestation.attester_index&lt;&#x2F;code&gt; in &lt;code&gt;get_beacon_committee(state, attestation.data.slot, index)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;If an attacker mutates the &lt;code&gt;index&lt;&#x2F;code&gt; field, the above rule verification will fail, and the message will be dropped. If implementations run the above check before registering the attestation in a &#x27;first-seen&#x27; cache, there&#x27;s no risk of cache pollution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Asynchronous ERC-4626 Tokenized Vaults</title>
        <published>2023-10-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Jeroen Offerijns</name><uri>https://github.com/hieronx</uri>
	</author>
	
	<author>
		<name>Alina Sinelnikova</name><uri>https://github.com/ilinzweilin</uri>
	</author>
	
	<author>
		<name>Vikram Arun</name><uri>https://github.com/vikramarun</uri>
	</author>
	
	<author>
		<name>Joey Santoro</name><uri>https://github.com/joeysantoro</uri>
	</author>
	
	<author>
		<name>Farhaan Ali</name><uri>https://github.com/0xfarhaan</uri>
	</author>
	
	<author>
		<name>João Martins</name><uri>https://github.com/0xTimepunk</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7540/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7540-asynchronous-erc-4626-tokenized-vaults/16153" />
        

        <id>https://wg-eips.ritovision.com/7540/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7540"
            label="ERC-7540" />
        

        
        

        
        <summary type="html">Extension of ERC-4626 with asynchronous deposit and redemption support</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7540/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; by adding support for asynchronous deposit and redemption flows. The async flows are called Requests.&lt;&#x2F;p&gt;
&lt;p&gt;New methods are added to asynchronously Request a deposit or redemption, and view the status of the Request. The existing &lt;code&gt;deposit&lt;&#x2F;code&gt;, &lt;code&gt;mint&lt;&#x2F;code&gt;, &lt;code&gt;withdraw&lt;&#x2F;code&gt;, and &lt;code&gt;redeem&lt;&#x2F;code&gt; ERC-4626 methods are used for executing Claimable Requests.&lt;&#x2F;p&gt;
&lt;p&gt;Implementations can choose whether to add asynchronous flows for deposits, redemptions, or both.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The ERC-4626 Tokenized Vaults standard has helped to make yield-bearing tokens more composable across decentralized finance. The standard is optimized for atomic deposits and redemptions up to a limit. If the limit is reached, no new deposits or redemptions can be submitted.&lt;&#x2F;p&gt;
&lt;p&gt;This limitation does not work well for any smart contract system with asynchronous actions or delays as a prerequisite for interfacing with the Vault (e.g. real-world asset protocols, undercollateralized lending protocols, cross-chain lending protocols, liquid staking tokens, or insurance safety modules).&lt;&#x2F;p&gt;
&lt;p&gt;This standard expands the utility of ERC-4626 Vaults for asynchronous use cases. The existing Vault interface (&lt;code&gt;deposit&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;withdraw&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;mint&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;redeem&lt;&#x2F;code&gt;) is fully utilized to claim asynchronous Requests.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions:&lt;&#x2F;h3&gt;
&lt;p&gt;The existing definitions from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; apply. In addition, this spec defines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Request: a request to enter (&lt;code&gt;requestDeposit&lt;&#x2F;code&gt;) or exit (&lt;code&gt;requestRedeem&lt;&#x2F;code&gt;) the Vault&lt;&#x2F;li&gt;
&lt;li&gt;Pending: the state where a Request has been made but is not yet Claimable&lt;&#x2F;li&gt;
&lt;li&gt;Claimable: the state where a Request is processed by the Vault enabling the user to claim corresponding &lt;code&gt;shares&lt;&#x2F;code&gt; (for async deposit) or &lt;code&gt;assets&lt;&#x2F;code&gt; (for async redeem)&lt;&#x2F;li&gt;
&lt;li&gt;Claimed: the state where a Request is finalized by the user and the user receives the output token (e.g. &lt;code&gt;shares&lt;&#x2F;code&gt; for a deposit Request)&lt;&#x2F;li&gt;
&lt;li&gt;Claim function: the corresponding Vault method to bring a Request to Claimed state (e.g. &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt; claims &lt;code&gt;shares&lt;&#x2F;code&gt; from &lt;code&gt;requestDeposit&lt;&#x2F;code&gt;). Lowercase claim always describes the verb action of calling a Claim function.&lt;&#x2F;li&gt;
&lt;li&gt;asynchronous deposit Vault: a Vault that implements asynchronous Requests for deposit flows&lt;&#x2F;li&gt;
&lt;li&gt;asynchronous redemption Vault: a Vault that implements asynchronous Requests for redemption flows&lt;&#x2F;li&gt;
&lt;li&gt;fully asynchronous Vault: a Vault that implements asynchronous Requests for both deposit and redemption flows&lt;&#x2F;li&gt;
&lt;li&gt;controller: owner of the Request, who can manage any actions related to the Request including claiming the &lt;code&gt;assets&lt;&#x2F;code&gt; or &lt;code&gt;shares&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;operator: an account that can manage Requests on behalf of another account.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;request-flows&quot;&gt;Request Flows&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7540&#x2F;&quot;&gt;ERC-7540 Vaults&lt;&#x2F;a&gt; MUST implement one or both of asynchronous deposit and redemption Request flows. If either flow is not implemented in a Request pattern, it MUST use the ERC-4626 standard synchronous interaction pattern.&lt;&#x2F;p&gt;
&lt;p&gt;All ERC-7540 asynchronous tokenized Vaults MUST implement ERC-4626 with overrides for certain behavior described below.&lt;&#x2F;p&gt;
&lt;p&gt;Asynchronous deposit Vaults MUST override the ERC-4626 specification as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;mint&lt;&#x2F;code&gt; methods do not transfer &lt;code&gt;assets&lt;&#x2F;code&gt; to the Vault, because this already happened on &lt;code&gt;requestDeposit&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;previewDeposit&lt;&#x2F;code&gt; and &lt;code&gt;previewMint&lt;&#x2F;code&gt; MUST revert for all callers and inputs.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Asynchronous redeem Vaults MUST override the ERC-4626 specification as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;redeem&lt;&#x2F;code&gt; and &lt;code&gt;withdraw&lt;&#x2F;code&gt; methods do not transfer &lt;code&gt;shares&lt;&#x2F;code&gt; to the Vault, because this already happened on &lt;code&gt;requestRedeem&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;owner&lt;&#x2F;code&gt; field of &lt;code&gt;redeem&lt;&#x2F;code&gt; and &lt;code&gt;withdraw&lt;&#x2F;code&gt; SHOULD be renamed to &lt;code&gt;controller&lt;&#x2F;code&gt;, and the controller MUST be &lt;code&gt;msg.sender&lt;&#x2F;code&gt; unless the &lt;code&gt;controller&lt;&#x2F;code&gt; has approved the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as an operator.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;previewRedeem&lt;&#x2F;code&gt; and &lt;code&gt;previewWithdraw&lt;&#x2F;code&gt; MUST revert for all callers and inputs.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;request-lifecycle&quot;&gt;Request Lifecycle&lt;&#x2F;h3&gt;
&lt;p&gt;After submission, Requests go through Pending, Claimable, and Claimed stages. An example lifecycle for a deposit Request is visualized in the table below.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;State&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;strong&gt;User&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;strong&gt;Vault&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Pending&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;requestDeposit(assets, controller, owner)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;asset.transferFrom(owner, vault, assets)&lt;&#x2F;code&gt;; &lt;code&gt;pendingDepositRequest[controller] += assets&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Claimable&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;em&gt;Internal Request fulfillment&lt;&#x2F;em&gt;:  &lt;code&gt;pendingDepositRequest[controller] -= assets&lt;&#x2F;code&gt;; &lt;code&gt;claimableDepositRequest[controller] += assets&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Claimed&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;deposit(assets, receiver, controller)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;claimableDepositRequest[controller] -= assets&lt;&#x2F;code&gt;; &lt;code&gt;vault.balanceOf[receiver] += shares&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Note that &lt;code&gt;maxDeposit&lt;&#x2F;code&gt; increases and decreases in sync with &lt;code&gt;claimableDepositRequest&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Requests MUST NOT skip or otherwise short-circuit the Claim state. In other words, to initiate and claim a Request, a user MUST call both request* and the corresponding Claim function separately, even in the same block. Vaults MUST NOT &quot;push&quot; tokens onto the user after a Request, users MUST &quot;pull&quot; the tokens via the Claim function.&lt;&#x2F;p&gt;
&lt;p&gt;For asynchronous Vaults, the exchange rate between &lt;code&gt;shares&lt;&#x2F;code&gt; and &lt;code&gt;assets&lt;&#x2F;code&gt; including fees and yield is up to the Vault implementation. In other words, pending redemption Requests MAY NOT be yield-bearing and MAY NOT have a fixed exchange rate.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;request-ids&quot;&gt;Request Ids&lt;&#x2F;h3&gt;
&lt;p&gt;The request ID (&lt;code&gt;requestId&lt;&#x2F;code&gt;) of a request is returned by the corresponding &lt;code&gt;requestDeposit&lt;&#x2F;code&gt; and &lt;code&gt;requestRedeem&lt;&#x2F;code&gt; functions.&lt;&#x2F;p&gt;
&lt;p&gt;Multiple requests may have the same &lt;code&gt;requestId&lt;&#x2F;code&gt;, so a given Request is discriminated by both the &lt;code&gt;requestId&lt;&#x2F;code&gt; and the &lt;code&gt;controller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Requests of the same &lt;code&gt;requestId&lt;&#x2F;code&gt; MUST be fungible with each other (except in the special case &lt;code&gt;requestId == 0&lt;&#x2F;code&gt; described below). I.e. all Requests with the same &lt;code&gt;requestId&lt;&#x2F;code&gt; MUST transition from Pending to Claimable at the same time and receive the same exchange rate between &lt;code&gt;assets&lt;&#x2F;code&gt; and &lt;code&gt;shares&lt;&#x2F;code&gt;. If a Request with &lt;code&gt;requestId != 0&lt;&#x2F;code&gt; becomes partially claimable, all requests of the same &lt;code&gt;requestId&lt;&#x2F;code&gt; MUST become claimable at the same pro-rata rate.&lt;&#x2F;p&gt;
&lt;p&gt;There are no assumptions or requirements of requests with different &lt;code&gt;requestId&lt;&#x2F;code&gt;. I.e. they MAY transition to Claimable at different times and exchange rates with no ordering or correlation enforced in any way.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;code&gt;requestId==0&lt;&#x2F;code&gt;, the Vault MUST use purely the &lt;code&gt;controller&lt;&#x2F;code&gt; to discriminate the request state. The Pending and Claimable state of multiple requests from the same &lt;code&gt;controller&lt;&#x2F;code&gt; would be aggregated. If a Vault returns &lt;code&gt;0&lt;&#x2F;code&gt; for the &lt;code&gt;requestId&lt;&#x2F;code&gt; of any request, it MUST return &lt;code&gt;0&lt;&#x2F;code&gt; for all requests.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;requestdeposit&quot;&gt;requestDeposit&lt;&#x2F;h4&gt;
&lt;p&gt;Transfers &lt;code&gt;assets&lt;&#x2F;code&gt; from &lt;code&gt;owner&lt;&#x2F;code&gt; into the Vault and submits a Request for asynchronous &lt;code&gt;deposit&lt;&#x2F;code&gt;. This places the Request in Pending state, with a corresponding increase in &lt;code&gt;pendingDepositRequest&lt;&#x2F;code&gt; for the amount &lt;code&gt;assets&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The output &lt;code&gt;requestId&lt;&#x2F;code&gt; is used to partially discriminate the request along with the &lt;code&gt;controller&lt;&#x2F;code&gt;. See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7540&#x2F;#request-ids&quot;&gt;Request Ids&lt;&#x2F;a&gt; section for more info.&lt;&#x2F;p&gt;
&lt;p&gt;When the Request is Claimable, &lt;code&gt;claimableDepositRequest&lt;&#x2F;code&gt; will be increased for the &lt;code&gt;controller&lt;&#x2F;code&gt;. &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt; can subsequently be called by &lt;code&gt;controller&lt;&#x2F;code&gt; to receive &lt;code&gt;shares&lt;&#x2F;code&gt;. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;shares&lt;&#x2F;code&gt; that will be received on &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt; MAY NOT be equivalent to the value of &lt;code&gt;convertToShares(assets)&lt;&#x2F;code&gt; at the time of Request, as the price can change between Request and Claim.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;approve&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;transferFrom&lt;&#x2F;code&gt; on &lt;code&gt;asset&lt;&#x2F;code&gt; as a deposit Request flow.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;owner&lt;&#x2F;code&gt; MUST equal &lt;code&gt;msg.sender&lt;&#x2F;code&gt; unless the &lt;code&gt;owner&lt;&#x2F;code&gt; has approved the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as an operator.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;assets&lt;&#x2F;code&gt; cannot be requested for &lt;code&gt;deposit&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;mint&lt;&#x2F;code&gt; (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Note that most implementations will require pre-approval of the Vault with the Vault&#x27;s underlying &lt;code&gt;asset&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;DepositRequest&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestDeposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;pendingdepositrequest&quot;&gt;pendingDepositRequest&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of requested &lt;code&gt;assets&lt;&#x2F;code&gt; in Pending state for the &lt;code&gt;controller&lt;&#x2F;code&gt; with the given &lt;code&gt;requestId&lt;&#x2F;code&gt; to &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT include any &lt;code&gt;assets&lt;&#x2F;code&gt; in Claimable state for &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;endingDepositRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;claimabledepositrequest&quot;&gt;claimableDepositRequest&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of requested &lt;code&gt;assets&lt;&#x2F;code&gt; in Claimable state for the &lt;code&gt;controller&lt;&#x2F;code&gt; with the given &lt;code&gt;requestId&lt;&#x2F;code&gt; to &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT include any &lt;code&gt;assets&lt;&#x2F;code&gt; in Pending state for &lt;code&gt;deposit&lt;&#x2F;code&gt; or &lt;code&gt;mint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;laimableDepositRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;requestredeem&quot;&gt;requestRedeem&lt;&#x2F;h4&gt;
&lt;p&gt;Assumes control of &lt;code&gt;shares&lt;&#x2F;code&gt; from &lt;code&gt;owner&lt;&#x2F;code&gt; and submits a Request for asynchronous &lt;code&gt;redeem&lt;&#x2F;code&gt;. This places the Request in Pending state, with a corresponding increase in &lt;code&gt;pendingRedeemRequest&lt;&#x2F;code&gt; for the amount &lt;code&gt;shares&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The output &lt;code&gt;requestId&lt;&#x2F;code&gt; is used to discriminate the request along with the &lt;code&gt;controller&lt;&#x2F;code&gt;. See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7540&#x2F;#request-ids&quot;&gt;Request Ids&lt;&#x2F;a&gt; section for more info.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;shares&lt;&#x2F;code&gt; MAY be temporarily locked in the Vault until the Claimable or Claimed state for accounting purposes, or they MAY be burned immediately upon &lt;code&gt;requestRedeem&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In either case, the &lt;code&gt;shares&lt;&#x2F;code&gt; MUST be removed from the custody of &lt;code&gt;owner&lt;&#x2F;code&gt; upon &lt;code&gt;requestRedeem&lt;&#x2F;code&gt; and burned by the time the request is Claimed.&lt;&#x2F;p&gt;
&lt;p&gt;Redeem Request approval of &lt;code&gt;shares&lt;&#x2F;code&gt; for a &lt;code&gt;msg.sender&lt;&#x2F;code&gt; NOT equal to &lt;code&gt;owner&lt;&#x2F;code&gt; may come either from ERC-20 approval over the &lt;code&gt;shares&lt;&#x2F;code&gt; of &lt;code&gt;owner&lt;&#x2F;code&gt; or if the &lt;code&gt;owner&lt;&#x2F;code&gt; has approved the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as an operator. This MUST be consistent with similar behaviour pointed out in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6909&#x2F;&quot;&gt;ERC-6909&lt;&#x2F;a&gt;, within &quot;Approvals and Operators&quot; section: &quot;In accordance with the transferFrom method, spenders with operator permission are not subject to allowance restrictions, spenders with infinite approvals SHOULD NOT have their allowance deducted on delegated transfers, but spenders with non-infinite approvals MUST have their balance deducted on delegated transfers.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;When the Request is Claimable, &lt;code&gt;claimableRedeemRequest&lt;&#x2F;code&gt; will be increased for the &lt;code&gt;controller&lt;&#x2F;code&gt;. &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt; can subsequently be called by &lt;code&gt;controller&lt;&#x2F;code&gt; to receive &lt;code&gt;assets&lt;&#x2F;code&gt;. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;assets&lt;&#x2F;code&gt; that will be received on &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt; MAY NOT be equivalent to the value of &lt;code&gt;convertToAssets(shares)&lt;&#x2F;code&gt; at the time of Request, as the price can change between Pending and Claimed.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;shares&lt;&#x2F;code&gt; cannot be requested for &lt;code&gt;redeem&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;withdraw&lt;&#x2F;code&gt; (due to withdrawal limit being reached, slippage, the owner not having enough shares, etc).&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;RedeemRequest&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestRedeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&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 class=&quot;z-entity z-name z-tag&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;pendingredeemrequest&quot;&gt;pendingRedeemRequest&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of requested &lt;code&gt;shares&lt;&#x2F;code&gt; in Pending state for the &lt;code&gt;controller&lt;&#x2F;code&gt; with the given &lt;code&gt;requestId&lt;&#x2F;code&gt; to &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT include any &lt;code&gt;shares&lt;&#x2F;code&gt; in Claimable state for &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;endingRedeemRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;claimableredeemrequest&quot;&gt;claimableRedeemRequest&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of requested &lt;code&gt;shares&lt;&#x2F;code&gt; in Claimable state for the &lt;code&gt;controller&lt;&#x2F;code&gt; with the given &lt;code&gt;requestId&lt;&#x2F;code&gt; to &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT include any &lt;code&gt;shares&lt;&#x2F;code&gt; in Pending state for &lt;code&gt;redeem&lt;&#x2F;code&gt; or &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;laimableRedeemRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;isoperator&quot;&gt;&lt;code&gt;isOperator&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Returns &lt;code&gt;true&lt;&#x2F;code&gt; if the &lt;code&gt;operator&lt;&#x2F;code&gt; is approved as an operator for a &lt;code&gt;controller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sOperator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;perator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tatus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;setoperator&quot;&gt;&lt;code&gt;setOperator&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Grants or revokes permissions for &lt;code&gt;operator&lt;&#x2F;code&gt; to manage Requests on behalf of the &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST set the operator status to the &lt;code&gt;approved&lt;&#x2F;code&gt; value.&lt;&#x2F;p&gt;
&lt;p&gt;MUST log the &lt;code&gt;OperatorSet&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return True.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;etOperator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;perator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uccess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;deposit-and-mint-overloaded-methods&quot;&gt;&lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;mint&lt;&#x2F;code&gt; overloaded methods&lt;&#x2F;h4&gt;
&lt;p&gt;Implementations MUST support an additional overloaded &lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;mint&lt;&#x2F;code&gt; method on the specification from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt;, with an additional &lt;code&gt;controller&lt;&#x2F;code&gt; input of type &lt;code&gt;address&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;deposit(uint256 assets, address receiver, address controller)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;mint(uint256 shares, address receiver, address controller)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Calls MUST revert unless &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is either equal to &lt;code&gt;controller&lt;&#x2F;code&gt; or an operator approved by &lt;code&gt;controller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;controller&lt;&#x2F;code&gt; field is used to discriminate the Request for which the &lt;code&gt;assets&lt;&#x2F;code&gt; should be claimed in the case where &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is NOT &lt;code&gt;controller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When the &lt;code&gt;Deposit&lt;&#x2F;code&gt; event is emitted, the first parameter MUST be the &lt;code&gt;controller&lt;&#x2F;code&gt;, and the second parameter MUST be the &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;depositrequest&quot;&gt;DepositRequest&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;owner&lt;&#x2F;code&gt; has locked &lt;code&gt;assets&lt;&#x2F;code&gt; in the Vault to Request a deposit with request ID &lt;code&gt;requestId&lt;&#x2F;code&gt;. &lt;code&gt;controller&lt;&#x2F;code&gt; controls this Request. &lt;code&gt;sender&lt;&#x2F;code&gt; is the caller of the &lt;code&gt;requestDeposit&lt;&#x2F;code&gt; which may not be equal to the &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be emitted when a deposit Request is submitted using the &lt;code&gt;requestDeposit&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;epositRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;redeemrequest&quot;&gt;RedeemRequest&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;sender&lt;&#x2F;code&gt; has locked &lt;code&gt;shares&lt;&#x2F;code&gt;, owned by &lt;code&gt;owner&lt;&#x2F;code&gt;, in the Vault to Request a redemption. &lt;code&gt;controller&lt;&#x2F;code&gt; controls this Request, but is not necessarily the &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be emitted when a redemption Request is submitted using the &lt;code&gt;requestRedeem&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;edeemRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equestId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;operatorset&quot;&gt;&lt;code&gt;OperatorSet&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;controller&lt;&#x2F;code&gt; has set the &lt;code&gt;approved&lt;&#x2F;code&gt; status to an &lt;code&gt;operator&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged when the operator status is set.&lt;&#x2F;p&gt;
&lt;p&gt;MAY be logged when the operator status is set to the same status it was before the current call.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; O&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;peratorSet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontroller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;perator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-165-support&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; support&lt;&#x2F;h3&gt;
&lt;p&gt;Smart contracts implementing this Vault standard MUST implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;All asynchronous Vaults MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if either &lt;code&gt;0xe3bc4e65&lt;&#x2F;code&gt; (representing the operator methods that all ERC-7540 Vaults implement) or &lt;code&gt;0x2f0a18c5&lt;&#x2F;code&gt; (representing the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; interface) is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;p&gt;
&lt;p&gt;Asynchronous deposit Vaults MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0xce3bbe50&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;p&gt;
&lt;p&gt;Asynchronous redemption Vaults MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0x620ee8e4&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-7575-support&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; support&lt;&#x2F;h3&gt;
&lt;p&gt;Smart contracts implementing this Vault standard MUST implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7575&#x2F;&quot;&gt;ERC-7575&lt;&#x2F;a&gt; standard (in particular the &lt;code&gt;share&lt;&#x2F;code&gt; method).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;including-request-ids-but-not-including-a-claim-by-id-method&quot;&gt;Including Request IDs but not including a Claim by ID method&lt;&#x2F;h3&gt;
&lt;p&gt;Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible tokens due to their asynchronicity. However, trying to pigeonhole all ERC-7540 Vaults into supporting &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; for Requests would create too much interface bloat.&lt;&#x2F;p&gt;
&lt;p&gt;Using both an id and address to discriminate Requests allows for any of these use cases to be developed at an external layer without adding too much complexity to the core interface.&lt;&#x2F;p&gt;
&lt;p&gt;Certain Vaults, especially &lt;code&gt;requestId==0&lt;&#x2F;code&gt; cases, benefit from using the underlying &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; methods for claiming because there is no discrimination at the &lt;code&gt;requestId&lt;&#x2F;code&gt; level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero request ID with support for claiming and transferring requests discriminated also with a &lt;code&gt;requestId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;symmetry-and-non-inclusion-of-requestwithdraw-and-requestmint&quot;&gt;Symmetry and Non-inclusion of requestWithdraw and requestMint&lt;&#x2F;h3&gt;
&lt;p&gt;In ERC-4626, the spec was written to be fully symmetrical with respect to converting &lt;code&gt;assets&lt;&#x2F;code&gt; and &lt;code&gt;shares&lt;&#x2F;code&gt; by including deposit&#x2F;withdraw and mint&#x2F;redeem.&lt;&#x2F;p&gt;
&lt;p&gt;Due to the nature of Requests, asynchronous Vaults can only operate with certainty on the quantity that is fully known at the time of the Request (&lt;code&gt;assets&lt;&#x2F;code&gt; for &lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;shares&lt;&#x2F;code&gt; for &lt;code&gt;redeem&lt;&#x2F;code&gt;). Therefore the deposit Request flow cannot work with a &lt;code&gt;mint&lt;&#x2F;code&gt; call, because the amount of &lt;code&gt;assets&lt;&#x2F;code&gt; for the requested &lt;code&gt;shares&lt;&#x2F;code&gt; amount may fluctuate before the fulfillment of the Request. Likewise, the redemption Request flow cannot work with a &lt;code&gt;withdraw&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;optionality-of-flows&quot;&gt;Optionality of Flows&lt;&#x2F;h3&gt;
&lt;p&gt;Certain use cases are only asynchronous on one side of the deposit or redeem Request flow. A good example of an asynchronous redemption Vault is a liquid staking token. The unstaking period necessitates support for asynchronous withdrawals, however, deposits can be fully synchronous.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;non-inclusion-of-a-request-cancelation-flow&quot;&gt;Non-inclusion of a Request Cancelation Flow&lt;&#x2F;h3&gt;
&lt;p&gt;In many cases, canceling a Request may not be straightforward or even technically feasible. The state transition of cancelations could be synchronous or asynchronous, and the way to claim a cancelation interfaces with the remaining Vault functionality in complex ways.&lt;&#x2F;p&gt;
&lt;p&gt;A separate EIP should be developed to standardize the behavior of cancelling a pending Request. Defining the cancel flow is still important for certain classes of use cases for which the fulfillment of a Request can take a considerable amount of time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;request-implementation-flexibility&quot;&gt;Request Implementation Flexibility&lt;&#x2F;h3&gt;
&lt;p&gt;The standard is flexible enough to support a wide range of interaction patterns for Request flows. Pending Requests can be handled via internal accounting, globally or on per-user levels, use ERC-20 or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise yield on redemption Requests can accrue or not, and the exchange rate of any Request may be fixed or variable depending on the implementation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-allowing-short-circuiting-for-claims&quot;&gt;Not Allowing Short-circuiting for Claims&lt;&#x2F;h3&gt;
&lt;p&gt;If claims can short-circuit, this creates ambiguity for integrators and complicates the interface with overloaded behavior on Request functions.&lt;&#x2F;p&gt;
&lt;p&gt;An example of a short-circuiting Request flow could be as follows: user triggers a Request which enters Pending state. When the Vault fulfills the Request, the corresponding &lt;code&gt;assets&#x2F;shares&lt;&#x2F;code&gt; are pushed straight to the user. This requires only 1 step on the user&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;This approach has a few issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cost&#x2F;lack of scalability: as the number of vault users grows it can become intractably expensive to offload the Claim costs to the Vault operator&lt;&#x2F;li&gt;
&lt;li&gt;hinders integration potential: Vault integrators would need to handle both the 2-step and 1-step cases, with the 1-step pushing arbitrary tokens in from an unknown Request at an unknown time. This pushes complexity out onto integrators and reduces the standard&#x27;s utility.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The 2-step approach used in the standard may be abstracted into a 1-step approach from the user perspective through the use of routers, relayers, message signing, or account abstraction.&lt;&#x2F;p&gt;
&lt;p&gt;In the case where a Request may become Claimable immediately in the same block, there can be router contracts that atomically check for Claimable amounts immediately upon Request. Frontends can dynamically route Requests in this way depending on the state and implementation of the Vault to handle this edge case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;no-outputs-for-request-functions&quot;&gt;No Outputs for Request Functions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;requestDeposit&lt;&#x2F;code&gt; and &lt;code&gt;requestRedeem&lt;&#x2F;code&gt; may not have a known exchange rate that will happen when the Request becomes Claimed. Returning the corresponding &lt;code&gt;assets&lt;&#x2F;code&gt; or &lt;code&gt;shares&lt;&#x2F;code&gt; could not work in this case.&lt;&#x2F;p&gt;
&lt;p&gt;The Requests could also output a timestamp representing the minimum amount of time expected for the Request to become Claimable, however, not all Vaults will be able to return a reliable timestamp.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;no-event-for-claimable-state&quot;&gt;No Event for Claimable State&lt;&#x2F;h3&gt;
&lt;p&gt;The state transition of a Request from Pending to Claimable happens at the Vault implementation level and is not specified in the standard. Requests may be batched into the Claimable state, or the state may transition automatically after a timestamp has passed. It is impractical to require an event to emit after a Request becomes Claimable at the user or batch level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reversion-of-preview-functions-in-async-request-flows&quot;&gt;Reversion of Preview Functions in Async Request Flows&lt;&#x2F;h3&gt;
&lt;p&gt;The preview functions do not take an address parameter, therefore the only way to discriminate discrepancies in the exchange rate is via the &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. However, this could lead to integration&#x2F;implementation complexities where support contracts cannot determine the output of a claim on behalf of a &lt;code&gt;controller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, there is no on-chain benefit to previewing the Claim step as the only valid state transition is to Claim anyway. If the output of a Claim is undesirable for any reason, the calling contract can revert on the output of that function call.&lt;&#x2F;p&gt;
&lt;p&gt;It reduces code and implementation complexity at little to no cost to simply mandate reversion for the preview functions of an async flow.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mandated-support-for-erc-165&quot;&gt;Mandated Support for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Implementing support for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; is mandated because of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7540&#x2F;#optionality-of-flows&quot;&gt;optionality of flows&lt;&#x2F;a&gt;. Integrations can use the &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method to check whether a vault is fully asynchronous, partially asynchronous, or fully synchronous (for which it is just following the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt;), and use a single contract to support all cases.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-allowing-pending-claims-to-be-fungible&quot;&gt;Not Allowing Pending Claims to be Fungible&lt;&#x2F;h3&gt;
&lt;p&gt;The async pending claims represent a sort of semi-fungible intermediate share class. Vaults can elect to wrap these claims in any token standard they like, for example, ERC-20, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;, or ERC-721 depending on the use case. This is intentionally left out of the spec to provide flexibility to implementers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The interface is fully backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt;. The specification of the &lt;code&gt;deposit&lt;&#x2F;code&gt;, &lt;code&gt;mint&lt;&#x2F;code&gt;, &lt;code&gt;redeem&lt;&#x2F;code&gt;, and &lt;code&gt;withdraw&lt;&#x2F;code&gt; methods is different as described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7540&#x2F;#specification&quot;&gt;Specification&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; pendingDepositRequest&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; claimableDepositRequest&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; controller &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; isOperator&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; requestDeposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; controller&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; requestId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;assets &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        requestId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; no requestId associated with this request&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;        asset&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; asset here is the Vault underlying asset&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;        pendingDepositRequest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;controller&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DepositRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;controller&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; requestId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; assets&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; requestId&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Include some arbitrary transition logic here from Pending to Claimable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; controller&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;assets &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;controller &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;controller&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        claimableDepositRequest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;controller&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; underflow would revert if not enough claimable assets&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;        shares &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertToShares&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;assets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this naive example uses the instantaneous exchange rate. It may be more common to use the rate locked in upon Claimable stage.&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;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;receiver&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;controller&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; shares&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;        isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;operator&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OperatorSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;In general, asynchronicity concerns make state transitions in the Vault much more complex and vulnerable to security risks. Access control on Vault operations, clear documentation of state transitions, and invariant checks should all be performed to mitigate these risks. For example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The view methods for viewing Pending and Claimable request states (e.g. pendingDepositRequest) are estimates useful for display purposes but can be outdated. The inability to know the final exchange rate on any Request requires users to trust the implementation of the asynchronous Vault in the computation of the exchange rate and fulfillment of their Request.&lt;&#x2F;li&gt;
&lt;li&gt;Shares or assets locked for Requests can be stuck in the Pending state. Vaults may elect to allow for the fungibility of pending claims or implement some cancellation functionality to protect users.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;operators&quot;&gt;Operators&lt;&#x2F;h3&gt;
&lt;p&gt;An operator has the ability to transfer the &lt;code&gt;asset&lt;&#x2F;code&gt; of the vault from the approver to any address, and simultaneously grants control over the &lt;code&gt;share&lt;&#x2F;code&gt; of the vault.&lt;&#x2F;p&gt;
&lt;p&gt;Any user approving an operator must trust that operator with both the &lt;code&gt;asset&lt;&#x2F;code&gt; and &lt;code&gt;share&lt;&#x2F;code&gt; of the Vault.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Native Asset ERC-4626 Tokenized Vault</title>
        <published>2023-10-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Joey Santoro</name><uri>https://github.com/joeysantoro</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7535/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7535-eth-native-asset-tokenized-vault/16068" />
        

        <id>https://wg-eips.ritovision.com/7535/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7535"
            label="ERC-7535" />
        

        
        

        
        <summary type="html">ERC-4626 Tokenized Vaults with Ether (Native Asset) as the underlying asset</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7535/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; spec with an identical interface and behavioral overrides for handling Ether or any native asset as the underlying.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A standard for tokenized ETH Vaults has the same benefits as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt;, particularly in the case of Liquid Staking Tokens, (i.e. fungible &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; wrappers around ETH staking).&lt;&#x2F;p&gt;
&lt;p&gt;Maintaining the same exact interface as ERC-4626 further amplifies the benefits as the standard will be maximally compatible with existing ERC-4626 tooling and protocols.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;All &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7535&#x2F;&quot;&gt;ERC-7535&lt;&#x2F;a&gt; tokenized Vaults MUST implement ERC-4626 (and by extension ERC-20) with behavioral overrides for the methods &lt;code&gt;asset&lt;&#x2F;code&gt;, &lt;code&gt;deposit&lt;&#x2F;code&gt;, and &lt;code&gt;mint&lt;&#x2F;code&gt; specified below.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-4626-breaking-changes&quot;&gt;ERC-4626 Breaking Changes&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Any &lt;code&gt;assets&lt;&#x2F;code&gt; quantity refers to wei of Ether rather than ERC-20 balances.&lt;&#x2F;li&gt;
&lt;li&gt;Any ERC-20 &lt;code&gt;transfer&lt;&#x2F;code&gt; calls are replaced by Ether transfer (&lt;code&gt;send&lt;&#x2F;code&gt; or &lt;code&gt;call&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Any ERC-20 &lt;code&gt;transferFrom&lt;&#x2F;code&gt; approval flows for &lt;code&gt;asset&lt;&#x2F;code&gt; are not implemented&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;mint&lt;&#x2F;code&gt; have state mutability &lt;code&gt;payable&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;deposit&lt;&#x2F;code&gt; uses &lt;code&gt;msg.value&lt;&#x2F;code&gt; as the primary input and MAY ignore &lt;code&gt;assets&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;asset&quot;&gt;asset&lt;&#x2F;h4&gt;
&lt;p&gt;MUST return &lt;code&gt;0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&lt;&#x2F;code&gt; per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7528&#x2F;&quot;&gt;ERC-7528&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssetTokenAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;deposit&quot;&gt;deposit&lt;&#x2F;h4&gt;
&lt;p&gt;Mints &lt;code&gt;shares&lt;&#x2F;code&gt; Vault shares to &lt;code&gt;receiver&lt;&#x2F;code&gt; by depositing exactly &lt;code&gt;msg.value&lt;&#x2F;code&gt; of Ether.&lt;&#x2F;p&gt;
&lt;p&gt;MUST have state mutability of &lt;code&gt;payable&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST use &lt;code&gt;msg.value&lt;&#x2F;code&gt; as the primary input parameter for calculating the &lt;code&gt;shares&lt;&#x2F;code&gt; output. I.e. MAY ignore &lt;code&gt;assets&lt;&#x2F;code&gt; parameter as an input.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Deposit&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;msg.value&lt;&#x2F;code&gt; cannot be deposited (due to deposit limit being reached, slippage, etc).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;mint&quot;&gt;mint&lt;&#x2F;h4&gt;
&lt;p&gt;Mints exactly &lt;code&gt;shares&lt;&#x2F;code&gt; Vault shares to &lt;code&gt;receiver&lt;&#x2F;code&gt; by depositing &lt;code&gt;assets&lt;&#x2F;code&gt; of ETH.&lt;&#x2F;p&gt;
&lt;p&gt;MUST have state mutability of &lt;code&gt;payable&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Deposit&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;shares&lt;&#x2F;code&gt; cannot be minted (due to deposit limit being reached, slippage, the user not sending a large enough &lt;code&gt;msg.value&lt;&#x2F;code&gt; of Ether to the Vault contract, etc).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;p&gt;The event usage MUST be identical to ERC-4626.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wrapped-eth&quot;&gt;Wrapped ETH&lt;&#x2F;h3&gt;
&lt;p&gt;Any ERC-4626 Vault that uses a Wrapped ETH ERC-20 as the &lt;code&gt;asset&lt;&#x2F;code&gt; MUST NOT implement ERC-7535. ERC-7535 only applies to native ETH.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standard was designed to maximize compatibility with ERC-4626 while minimizing additional opinionated details on the interface. Examples of this decision rationale are described below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;maintaining the redundant &lt;code&gt;assets&lt;&#x2F;code&gt; input to the &lt;code&gt;deposit&lt;&#x2F;code&gt; function while making its usage optional&lt;&#x2F;li&gt;
&lt;li&gt;not enforcing a relationship between &lt;code&gt;msg.value&lt;&#x2F;code&gt; and &lt;code&gt;assets&lt;&#x2F;code&gt; in a &lt;code&gt;mint&lt;&#x2F;code&gt; call&lt;&#x2F;li&gt;
&lt;li&gt;not enforcing any behaviors or lack thereof for &lt;code&gt;fallback&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;__default__&lt;&#x2F;code&gt; methods, payability on additional vault functions, or handling ETH forcibly sent to the contract&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All breaking implementation level changes with ERC-4626 are purely to accomodate for the usage of Ether or any native asset instead of an ERC-20 token.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;allowing-assets-parameter-to-be-ignored-in-a-deposit&quot;&gt;Allowing assets Parameter to be Ignored in a Deposit&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;msg.value&lt;&#x2F;code&gt; must always be passed anyway to fund a &lt;code&gt;deposit&lt;&#x2F;code&gt;, therefore it may as well be treated as the primary input number. Allowing &lt;code&gt;assets&lt;&#x2F;code&gt; to be used either forces a strict equality and extra unnecessary gas overhead for redundancy, or allows different values which could cause footguns and undefined behavior.&lt;&#x2F;p&gt;
&lt;p&gt;The last option which could work is to require that &lt;code&gt;assets&lt;&#x2F;code&gt; MUST be 0, but this still requires gas to enforce at the implementation level and can more easily be left unspecified, as the input is functionally ignorable in the spec as written.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;allowing-msg-value-to-not-equal-assets-output-in-a-mint&quot;&gt;Allowing msg.value to Not Equal assets Output in a Mint&lt;&#x2F;h3&gt;
&lt;p&gt;There may be many cases where a user deposits slightly too much Ether in a &lt;code&gt;mint&lt;&#x2F;code&gt; call. In these cases, enforcing &lt;code&gt;msg.value&lt;&#x2F;code&gt; to equal &lt;code&gt;assets&lt;&#x2F;code&gt; would cause unnecessary reversions. It is up to the vault implementer to decide whether to refund or absorb any excess Ether, and up to depositors to deposit as close to the exact amount as possible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-7535 is fully backward compatible with ERC-4626 at the function interface level. Certain implementation behaviors are different due to the fact that ETH is not ERC-20 compliant, such as the priority of &lt;code&gt;msg.value&lt;&#x2F;code&gt; over &lt;code&gt;assets&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It has no known compatibility issues with other standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;In addition to all security considerations of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt;, there are security implications of having ETH as the Vault asset.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;call-vs-send&quot;&gt;&lt;code&gt;call&lt;&#x2F;code&gt; vs &lt;code&gt;send&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Contracts should take care when using &lt;code&gt;call&lt;&#x2F;code&gt; to transfer ETH, as this allows additional reentrancy vulnerabilities and arbitrary code execution beyond what is possible with trusted ERC-20 tokens.&lt;&#x2F;p&gt;
&lt;p&gt;It is safer to simply &lt;code&gt;send&lt;&#x2F;code&gt; ETH with a small gas stipend.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers should take extra precautions when deciding how to transfer ETH.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;forceful-eth-transfers&quot;&gt;Forceful ETH transfers&lt;&#x2F;h3&gt;
&lt;p&gt;ETH can be forced into any Vault through the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode. Implementers should validate that this does not disrupt Vault accounting in any way.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, any additional &lt;code&gt;payable&lt;&#x2F;code&gt; methods should be checked to ensure they do not disrupt Vault accounting.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wrapped-eth-1&quot;&gt;Wrapped ETH&lt;&#x2F;h3&gt;
&lt;p&gt;Smart contract systems which implement ERC-4626 should consider only supporting ERC-20 underlying assets, and default to using a Wrapped ETH ERC-20 instead of implementing ERC-7535 for handling ETH.&lt;&#x2F;p&gt;
&lt;p&gt;The subtle differences between ERC-4626 and ERC-7535 can introduce code fragmentation and security concerns.&lt;&#x2F;p&gt;
&lt;p&gt;Cleaner use cases for ERC-7535 are ETH exclusive, such as Wrapped ETH and Liquid Staking Tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ETH (Native Asset) Address Convention</title>
        <published>2023-10-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Joey Santoro</name><uri>https://github.com/joeysantoro</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7528/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7808-eth-native-asset-address-convention/15989" />
        

        <id>https://wg-eips.ritovision.com/7528/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7528"
            label="ERC-7528" />
        

        
        

        
        <summary type="html">An address placeholder for ETH when used in the same context as an ERC-20 token.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7528/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard proposes a convention for using the address &lt;code&gt;0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&lt;&#x2F;code&gt; in all contexts where an address is used to represent ETH in the same capacity as an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token. This would apply to both events where an address field would denote ETH or an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token, as well as discriminators such as the &lt;code&gt;asset&lt;&#x2F;code&gt; field of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; vault.&lt;&#x2F;p&gt;
&lt;p&gt;This standard generalizes to other EVM chains where the native asset is not ETH.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;ETH, being a fungible unit of value, often behaves similarly to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens. Protocols tend to implement a standard interface for ERC-20 tokens, and benefit from having the ETH implementation to closely mirror the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; implementations.&lt;&#x2F;p&gt;
&lt;p&gt;In many cases, protocols opt to use Wrapped ETH (e.g. WETH9 deployed at address 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 on Etherum Mainnet) for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compliance. In other cases, protocols will use native ETH due to gas considerations, or the requirement of using native ETH such as in the case of a Liquid Staking Token (LST).&lt;&#x2F;p&gt;
&lt;p&gt;In addition, protocols might create separate events for handling ETH native cases and ERC-20 cases. This creates data fragmentation and integration overhead for off-chain infrastructure. By having a strong convention for an ETH address to use for cases where it behaves like an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token, it becomes beneficial to use one single event format for both cases.&lt;&#x2F;p&gt;
&lt;p&gt;One intended use case for the standard is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; compliant LSTs which use ETH as the &lt;code&gt;asset&lt;&#x2F;code&gt;. This extends the benefits and tooling of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;ERC-4626&lt;&#x2F;a&gt; to LSTs and integrating protocols.&lt;&#x2F;p&gt;
&lt;p&gt;This standard allows protocols and off-chain data infrastructure to coordinate around a shared understanding that any time &lt;code&gt;0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&lt;&#x2F;code&gt; is used as an address in an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; context, it means ETH.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;This standard applies for all components of smart contract systems in which an address is used to identify an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token, and where native ETH is used in certain instances in place of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token. The usage of the term Token below means ETH or an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; in this context.&lt;&#x2F;p&gt;
&lt;p&gt;Any fields or events where an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; address is used, yet the underlying Token is ETH, the address field MUST return &lt;code&gt;0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Any fields or events where the Token is a non-enshrined wrapped ERC-20 version of ETH (i.e WETH9) MUST use that Token&#x27;s address and MUST NOT use &lt;code&gt;0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Where appropriate, the address should be checksummed. E.g. the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;55&#x2F;&quot;&gt;EIP-55&lt;&#x2F;a&gt; checksum is &lt;code&gt;0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;considered-alternative-addresses&quot;&gt;Considered alternative addresses&lt;&#x2F;h3&gt;
&lt;p&gt;Many existing implementations of the same use case as this standard use addresses such as 0x0, 0x1, and 0xe for gas efficiency of having leading zero bytes.&lt;&#x2F;p&gt;
&lt;p&gt;Ultimately, all of these addresses collide with potential precompile addresses and are less distinctive as identifiers for ETH.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&lt;&#x2F;code&gt; has the most current usage, is distinctive, and would not collide with any precompiles. These benefits outweigh the potential gas benefits of other alternatives.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard has no known compatibility issues with other standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Using ETH as a Token instead of WETH exposes smart contract systems to re-entrancy and similar classes of vulnerabilities. Implementers must take care to follow the industry standard development patterns (e.g.  checks-effects-interactions) when the Token is ETH.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>BLOBBASEFEE instruction</title>
        <published>2023-09-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Carl Beekhuizen</name><uri>https://github.com/carlbeek</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7516/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7516-blobbasefee-opcode/15761" />
        

        <id>https://wg-eips.ritovision.com/7516/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7516"
            label="EIP-7516" />
        

        
        

        
        <summary type="html">Instruction that returns the current data-blob base-fee</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7516/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add a &lt;code&gt;BLOBBASEFEE (0x4a)&lt;&#x2F;code&gt; instruction that returns the value of the blob base-fee of the current block it is executing in. It is the identical to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3198&#x2F;&quot;&gt;EIP-3198&lt;&#x2F;a&gt; (&lt;code&gt;BASEFEE&lt;&#x2F;code&gt; opcode) except that it returns the blob base-fee as per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The intended use case would be for contracts to get the value of the blob base-fee. This feature enables blob-data users to programmatically account for the blob gas price, eg:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Allow rollup contracts to trustlessly account for blob data usage costs.&lt;&#x2F;li&gt;
&lt;li&gt;Blob gas futures can be implemented based on it which allows for blob users to smooth out data blob costs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Add a &lt;code&gt;BLOBBASEFEE&lt;&#x2F;code&gt; instruction with opcode &lt;code&gt;0x4a&lt;&#x2F;code&gt;, with gas cost &lt;code&gt;2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Op&lt;&#x2F;th&gt;&lt;th&gt;Input&lt;&#x2F;th&gt;&lt;th&gt;Output&lt;&#x2F;th&gt;&lt;th&gt;Cost&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0x4a&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;BLOBBASEFEE&lt;&#x2F;code&gt; returns the result of the &lt;code&gt;get_blob_gasprice(header) -&amp;gt; int&lt;&#x2F;code&gt; function as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;#gas-accounting&quot;&gt;EIP-4844 §Gas accounting&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gas-cost&quot;&gt;Gas cost&lt;&#x2F;h3&gt;
&lt;p&gt;The value of the blob base-fee is needed to process data-blob transactions. That means its value is already available before running the EVM code.
The instruction does not add extra complexity and additional read&#x2F;write operations, hence the choice of &lt;code&gt;2&lt;&#x2F;code&gt; gas cost. This is also identical to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3198&#x2F;&quot;&gt;EIP-3198&lt;&#x2F;a&gt; (&lt;code&gt;BASEFEE&lt;&#x2F;code&gt; opcode)&#x27;s cost as it just makes available data that is in the header.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no known backward compatibility issues with this instruction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;nominal-case&quot;&gt;Nominal Case&lt;&#x2F;h3&gt;
&lt;p&gt;Assume calling &lt;code&gt;get_blob_gasprice(header)&lt;&#x2F;code&gt; (as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;#gas-accounting&quot;&gt;EIP-4844 §Gas accounting&lt;&#x2F;a&gt;) on the current block&#x27;s header returns &lt;code&gt;7 wei&lt;&#x2F;code&gt;:
&lt;code&gt;BLOBBASEFEE&lt;&#x2F;code&gt; should push the value &lt;code&gt;7&lt;&#x2F;code&gt; (left padded byte32) to the stack.&lt;&#x2F;p&gt;
&lt;p&gt;Bytecode: &lt;code&gt;0x4900&lt;&#x2F;code&gt; (&lt;code&gt;BLOBBASEFEE, STOP&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pc&lt;&#x2F;th&gt;&lt;th&gt;Op&lt;&#x2F;th&gt;&lt;th&gt;Cost&lt;&#x2F;th&gt;&lt;th&gt;Stack&lt;&#x2F;th&gt;&lt;th&gt;RStack&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;BLOBBASEFEE&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;STOP&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;[7]&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Output: 0x
Consumed gas: &lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;comprehensive-test-suite&quot;&gt;Comprehensive Test Suite&lt;&#x2F;h3&gt;
&lt;p&gt;A complete suite of tests can be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;blob&#x2F;1983444bbe1a471886ef7c0e82253ffe2a4053e1&#x2F;tests&#x2F;cancun&#x2F;eip7516_blobgasfee&#x2F;test_blobgasfee_opcode.py&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The value of the blob base-fee is not sensitive and is publicly accessible in the block header. There are no known security implications with this instruction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Add Max Epoch Churn Limit</title>
        <published>2023-09-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>dapplion</name><uri>https://github.com/dapplion</uri>
	</author>
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7514/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7514-add-max-epoch-churn-limit/15709" />
        

        <id>https://wg-eips.ritovision.com/7514/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7514"
            label="EIP-7514" />
        

        
        

        
        <summary type="html">Modify the churn limit function to upper bound it to a max value</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7514/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Update the maximum validator growth rate from an exponential to a linear increase by capping the epoch churn limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal aims to mitigate the negative externalities of very high level of total ETH supply staked before a proper solution is implemented. In other words, this proposal accepts the complexities of changing the rewards curve and is meant only to slow down growth.&lt;&#x2F;p&gt;
&lt;p&gt;In the event that the deposit queue stays 100% full, the share of ETH supply staked will reach 50% by May 2024, 75% by September 2024, and 100% by December 2024. While rewards decrease as the validator set size increases, at 100% of ETH supply staked, yearly consensus rewards alone (excluding MEV&#x2F;transaction fees) for validators still represent ~1.6% of their stake. This small yield does not necessarily dissuade additional capital staking due to the often much higher and unpredictable yields from MEV. As such, the equilibrium point of the validator set size can be close to its maximum possible. Liquid staking tokens (LSTs) also contribute to this, given stakers can use them as they use unstaked ETH.&lt;&#x2F;p&gt;
&lt;p&gt;As the levels of ETH staked increase, more strain is put on the consensus layer. A larger number of validators leads to an increase in gossip messages, as well as a growing Beacon state size. Additionally, as the amount of stake grows, it&#x27;s unclear how much marginal security benefits come from additional economic weight.&lt;&#x2F;p&gt;
&lt;p&gt;The Beacon Chain validator reward function was chosen before its launch in 2020. PoS research and reward curve design were performed in a pre-MEV world. Much has changed since then, including the Beacon chain achieving unprecedented success, beyond the original intended targets of stake rate. In light of this, it is worth discussing whether Beacon chain validator rewards should be adjusted to better match today&#x27;s reality, potentially to discourage staking past a certain point.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not attempt to do this, but to allow more time for the community to have these discussions. By limiting the epoch churn limit now, the time to reach critical milestones of total ETH supply staked are significantly delayed. This allows more time for research into more comprehensive solutions, and for community consensus around them to emerge.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution layer&lt;&#x2F;h3&gt;
&lt;p&gt;This requires no changes to the Execution Layer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;get_validator_activation_churn_limit&lt;&#x2F;code&gt; with upper bound &lt;code&gt;MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;process_registry_updates&lt;&#x2F;code&gt; to use bounded activation churn limit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The full specification of the proposed change can be found in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;69d34dc4ee3d026ca437d1b6875b218e8aaf3a5c&#x2F;specs&#x2F;deneb&#x2F;beacon-chain.md&quot;&gt;&lt;code&gt;&#x2F;specs&#x2F;deneb&#x2F;beacon-chain.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;max-per-epoch-churn-limit-value&quot;&gt;&lt;code&gt;MAX_PER_EPOCH_CHURN_LIMIT&lt;&#x2F;code&gt; value&lt;&#x2F;h3&gt;
&lt;p&gt;Depending on the specific constant selection the churn can &lt;em&gt;decrease&lt;&#x2F;em&gt; at the activation fork epoch. The Beacon chain spec can handle this without issues. During 2023 Q4 (projected Dencun activation) the churn value will range 14-16. The table below compares the projected validator set assuming a continuous full deposit queue.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;max-per-epoch-churn-limit-activation-date-dec-01-2023&quot;&gt;&lt;code&gt;MAX_PER_EPOCH_CHURN_LIMIT&lt;&#x2F;code&gt; activation date: Dec 01, 2023&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;Max Churn Limit&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;50% ETH staked&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;75% ETH staked&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;100% ETH staked&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;inf&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;May 28, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sep 25, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 18, 2024&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;16&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jul 23, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Apr 10, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 26, 2025&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;12&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Oct 09, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sep 21, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sep 04, 2026&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;8&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Mar 15, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Aug 18, 2026&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jan 21, 2028&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;6&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Aug 19, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jul 14, 2027&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jun 08, 2029&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;4&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jun 29, 2026&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;May 05, 2029&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Mar 12, 2032&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;max-per-epoch-churn-limit-activation-date-apr-01-2024&quot;&gt;&lt;code&gt;MAX_PER_EPOCH_CHURN_LIMIT&lt;&#x2F;code&gt; activation date: Apr 01, 2024&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;Max Churn Limit&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;50% ETH staked&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;75% ETH staked&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;100% ETH staked&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;inf&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;May 28, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sep 25, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 18, 2024&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;16&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jul 01, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Mar 18, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 04, 2025&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;12&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Aug 01, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jul 14, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jun 26, 2026&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;8&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Oct 01, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Mar 05, 2026&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Aug 08, 2027&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;6&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 01, 2024&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Oct 26, 2026&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sep 20, 2028&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;4&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Apr 02, 2025&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Feb 07, 2028&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dec 15, 2030&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Assuming that the earliest the next fork can happen is at the start of 2024 Q3, a value of 8 provides a significant reduction in projected size without causing a big drop in churn at a projected Dencun fork date. A value of 8 prevents reaching a level of 50% ETH staked for at least 1 full year even with a delayed dencun fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backward incompatible changes to the block validation rule set on the consensus layer and must be accompanied by a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases for this EIP can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;2297c09b7e457a13f7b2261a28cb45777be82f83&#x2F;tests&#x2F;core&#x2F;pyspec&#x2F;eth2spec&#x2F;test&#x2F;deneb&quot;&gt;&lt;code&gt;deneb&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; test suite of the &lt;code&gt;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP breaks the symmetry between the validator entry and exit queues, where the former is bound by &lt;code&gt;MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT&lt;&#x2F;code&gt; while the latter isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Physical Asset Redemption</title>
        <published>2023-08-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Lee Vidor</name><uri>https://github.com/V1d0r</uri>
	</author>
	
	<author>
		<name>David Tan</name><email>david@emergentx.org</email>
	</author>
	
	<author>
		<name>Lee Smith</name><email>lee@emergentx.org</email>
	</author>
	
	<author>
		<name>Gabriel Stoica</name><uri>https://github.com/gabrielstoica</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7578/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7578-physical-asset-redemption/17556" />
        

        <id>https://wg-eips.ritovision.com/7578/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7578"
            label="ERC-7578" />
        

        
        

        
        <summary type="html">Provides the holder of physical asset backed NFTs readily available real-world information on the underlying physical asset.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7578/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and implements additional functionality and information pertaining to the NFT’s underlying physical asset by capturing information that enables the holder of physical asset backed NFTs to verify authenticity and facilitate redemption of the underlying physical assets. This proposal is primarily aimed at providing transparency by disclosing details of involved parties and provides opportunity to define and make readily available relevant legal relationship between NFT holder and the owner&#x2F;holder of the respective underlying physical asset. This proposal makes the token issuer accountable to embed accurate information on a set of standardized information about the underlying physical asset and the involved key parties.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The first wave of NFT use cases encompass predominately the representation of ownership of digital assets. In view of the anticipated trend to tokenize any real-world asset, it is to be expected that the use cases of NFTs will rapidly grow and expand around physical assets. The absence of an embedded standardized set of information pertaining to the underlying physical asset together with lack of transparency of involved key parties, creates an unnecessary hurdle for NFT holders and potential users which might, as a result, hinder mass adoption of NFTs that are used as ownership representation of a specific physical asset.&lt;&#x2F;p&gt;
&lt;p&gt;Addressing the lack of readily available information and paving the way for mass adoption for a tokenized economy, this proposal requires that each minted token includes a defined number of predefined variables enabling verification of authenticity and facilitating redemption of the underlying physical asset.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;When a token is minted, its properties SHOULD be initialized beforehand, with each field being defined as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Token issuer&lt;&#x2F;strong&gt;: identification of an individual or entity minting the NFT
&lt;br&gt; &lt;em&gt;The token issuer is the key person connecting the physical asset and the digital representation. By identifying and disclosing the token issuer, a reference point is made instantly available to the NFT holder which allows them to conduct a due diligence on the NFT issuer and assessment of the NFT issuer’s trustworthiness. At the same time, it creates accountability for the token issuer which leads to overall improvement and standardisation of the NFT minting process. Token issuers will compete for best practices and recognition to gain advantages over competitors. A reputable NFT issuer will e.g. keep information on the legal owner of the physical asset prior to the minting of the underlying physical asset to satisfy any AML and KYC concerns. Ideally the NFT issuer is identified by a name but may also be identifiable via unique identification number or network ID that is issued by a service provider who stores relevant information on the NFT issuer.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Asset holder&lt;&#x2F;strong&gt;: identification of legal owner of underlying physical asset
&lt;br&gt; &lt;em&gt;In view of a redemption of the underlying physical asset and enforcing of legal rights, it is (from a legal perspective) essential for the NFT holder to identify the legal owner of the underlying physical asset. It allows the NFT holder to consider the legal counterparty risk. It cannot be assumed that the NFT issuer is the legal owner of the underlying physical asset, therefore it is vital for the NFT holder to have instant access to this additional information. Same as with the NFT issuer’s identity, the legal owner is ideally identified by a name but may also be identifiable via unique identification number or network ID that is issued by a service provider who stores relevant information on the legal owner.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage location&lt;&#x2F;strong&gt;: identification of storage location of underlying physical asset
&lt;br&gt; &lt;em&gt;Certain physical assets require specific storage conditions. A digital representation of an inappropriately stored physical asset may impact the value of the NFT significantly. Disclosing the storage location and making it directly accessible to the NFT holder, allows them to evaluate the storage risk of the underlying physical asset. In addition, it provides the NFT holder with a second point of contact for the enforcement of the redemption of the underlying physical asset.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Terms&lt;&#x2F;strong&gt;: identification of legal relationship
&lt;br&gt; &lt;em&gt;The disclosure and accessibility of the legal basis of the relationship between NFT holder and legal owner of the underlying physical asset promotes token issuers to stipulate and define the legal rights of the involved key parties. It furthermore allows the NFT Holder to conduct a legal risk and enforcement assessment. Ideally, the information is provided by embedding a link to the actual legal documentation such as an agreement or terms. The more information is accessible via the NFT, the better the NFT holder can assess the legal risks associated with enforcement of the redemption of the underlying physical asset.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Jurisdiction&lt;&#x2F;strong&gt;: governing law and jurisdiction
&lt;br&gt; &lt;em&gt;The applicable law is an extension of the legal contract disclosure and makes instantly available to the NFT holder or smart contract under what jurisdiction an enforcement would be governed without the need to review the details legal contract. This allows for an instant assessment of jurisdiction risk.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Declared value&lt;&#x2F;strong&gt;: value of the underlying asset
&lt;br&gt; &lt;em&gt;Certain auxiliary services such as insurance are tied to a value of the NFT and underlying physical asset. By defining a declared value, NFTs are able to be categorised in certain ways while the declared value provides an indication regarding the underlying asset’s value. The declared value of the underlying physical asset does not necessarily represent the market value.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;terms&lt;&#x2F;code&gt; parameter SHOULD be an HTTP link to a document that is stored on IPFS. This is to ensure that the document is immutable and can be verified by the NFT holder.&lt;&#x2F;p&gt;
&lt;p&gt;When a token with valid properties is to be burned, the properties MUST be removed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Struct encapsulating fields required to by the ERC-7578 standard to represent the physical asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The network or entity minting the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetHolder&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The legal owner of the physical asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; storageLocation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The physical location where the asset is stored&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; terms&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Link to IPFS contract, agreement or terms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; jurisdiction&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The legal justification set out in the terms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; declaredValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The declared value at time of token minting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Properties&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; tokenIssuer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; assetHolder&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; storageLocation&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; terms&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; jurisdiction&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Amount declaredValue&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Struct encapsulating fields describing the declared value of the physical asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; currency&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The currency of the amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The value of the amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; currency&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Required interface of an ERC-7578 compliant contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7578&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the properties of the `tokenId` token are set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The properties of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; properties&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the properties of the `tokenId` token are removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves all properties of the `tokenId` token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does NOT revert if token doesn&amp;#39;t exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token ID of the minted token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getPropertiesOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; properties&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When &lt;code&gt;properties&lt;&#x2F;code&gt; are set, the &lt;code&gt;PropertiesSet(uint256 indexed tokenId, Properties properties)&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;code&gt;properties&lt;&#x2F;code&gt; are removed, the &lt;code&gt;PropertiesRemoved(uint256 indexed tokenId)&lt;&#x2F;code&gt; event is emitted.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;getPropertiesOf(uint256 tokenId)&lt;&#x2F;code&gt; function MUST return the unique &lt;code&gt;properties&lt;&#x2F;code&gt; of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty &lt;code&gt;Properties&lt;&#x2F;code&gt; struct.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;By not initializing a token&#x27;s properties before minting, one risks that the asset&#x27;s provenance represented by the token cannot be established.&lt;&#x2F;p&gt;
&lt;p&gt;Contract level validation is not used on the properties as we believe the accuracy of the data declared is the responsibility of the token issuer. This builds trust on the token issuer and the token itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with ERC-721.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;An example of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; that includes this proposal using the OpenZeppelin ERC-721 v5 library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7578&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Properties&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Amount&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;interfaces&#x2F;IERC7578.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC7578&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@author&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; DESAT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Implementation of the ERC-7578: Physical Asset Redemption standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7578&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7578&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Thrown when the properties of a token are not initialized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesUninitialized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the properties of the `tokenId` token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Properties&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _properties&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initializes the name and symbol of the ERC-721 collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_name, _symbol) &lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC7578&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getPropertiesOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; properties&lt;&#x2F;span&gt;&lt;span&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&gt;        properties &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _properties&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initializes the ERC-7578 properties of the `tokenId` token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * WARNING: This method should only be called within a function that has appropriate access control&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * It is recommended to restrict access to trusted Externally Owned Accounts (EOAs),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * authorized contracts, or implement a Role-Based Access Control (RBAC) mechanism&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Failure to properly secure this method could lead to unauthorized modification of token properties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits a {PropertiesSet} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _setPropertiesOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        _properties&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Properties&lt;&#x2F;span&gt;&lt;span&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&gt;            tokenIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokenIssuer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assetHolder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assetHolder&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            storageLocation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;storageLocation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            terms&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;terms&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            jurisdiction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;jurisdiction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            declaredValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Amount&lt;&#x2F;span&gt;&lt;span&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&gt;                currency&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;declaredValue&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;currency&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; properties&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;declaredValue&lt;&#x2F;span&gt;&lt;span&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&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&gt;        }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _properties&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Removes the properties of the `tokenId` token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique identifier of the token whose properties are to be removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits a {PropertiesRemoved} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _removePropertiesOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        delete&lt;&#x2F;span&gt;&lt;span&gt; _properties&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Override of the {_update} function to remove the properties of the `tokenId` token or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * to check if they are set before minting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique identifier of the token being minted or burned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            _removePropertiesOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_properties&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokenIssuer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PropertiesUninitialized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; auth&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;To ensure authenticity, token properties must be set only via a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the represented asset. Additionally, proper access control mechanisms should be implemented to prevent unauthorized modifications of token properties after they are set.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Prevent ticket touting</title>
        <published>2023-07-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>LeadBest Consulting Group</name><email>service@getoken.io</email>
	</author>
	
	<author>
		<name>Sandy Sung</name><uri>https://github.com/sandy-sung-lb</uri>
	</author>
	
	<author>
		<name>Mars Peng</name><email>mars.peng@getoken.io</email>
	</author>
	
	<author>
		<name>Taien Wang</name><email>taien.wang@getoken.io</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7439/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/prevent-ticket-touting/15269" />
        

        <id>https://wg-eips.ritovision.com/7439/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7439"
            label="ERC-7439" />
        

        
        

        
        <summary type="html">An interface for customers to resell their tickets via authorized ticket resellers.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7439/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of  &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and defines standard functions outlining a scope for ticketing agents or event organizers to take preventative actions to stop audiences being exploited in the ticket scalping market and allow customers to resell their tickets via authorized ticket resellers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Industrial-scale ticket touting has been a longstanding issue, with its associated fraud and criminal problems leading to unfortunate incidents and waste of social resources. It is also hugely damaging to artists at all levels of their careers and to related businesses across the board. Although the governments of various countries have begun to legislate to restrict the behavior of scalpers, the effect is limited. They still sold tickets for events at which resale was banned or did not yet own then obtained substantial illegal profits from speculative selling. We consulted many opinions to provide a consumer-friendly resale interface, enabling buyers to resell or reallocate a ticket at the price they initially paid or less is the efficient way to rip off “secondary ticketing”.that enables ticketing agents to utilize&lt;&#x2F;p&gt;
&lt;p&gt;The typical ticket may be a &quot;piece of paper&quot; or even a voucher in your email inbox, making it easy to counterfeit or circulate. To restrict the transferability of these tickets, we have designed a mechanism that prohibits ticket transfers for all parties, including the ticket owner, except for specific accounts that are authorized to transfer tickets. The specific accounts may be ticketing agents, managers, promoters and authorized resale platforms. Therefore, the ticket touts are unable to transfer tickets as they wish. Furthermore, to enhance functionality, we have implemented a token info schema to each ticket,  allowing only authorized accounts(excluding the owner) to modify these records.&lt;&#x2F;p&gt;
&lt;p&gt;This standard defines a framework that enables ticketing agents to utilize &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; tokens as event tickets and restricts token transferability to prevent ticket touting. By implementing this standard, we aim to protect customers from scams and fraudulent activities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The interface and structure referenced here are as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;TokenInfo
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;signature&lt;&#x2F;code&gt;: Recommend that the adapter self-defines what to sign using the user&#x27;s private key or agent&#x27;s private key to prove the token validity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;status&lt;&#x2F;code&gt;: Represent token current status.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;expireTime&lt;&#x2F;code&gt;: Recommend set to the event due time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;TokenStatus
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Sold&lt;&#x2F;code&gt;: When a token is sold, it MUST change to &lt;code&gt;Sold&lt;&#x2F;code&gt;. The token is valid in this status.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Resell&lt;&#x2F;code&gt;: When a token is in the secondary market, it MUST be changed to Resell. The token is valid in this status.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Void&lt;&#x2F;code&gt;: When the token owner engages in an illegal transaction, the token status MUST be set to Void, and the token is invalid in this status.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Redeemed&lt;&#x2F;code&gt;:  When the token is used, it is RECOMMENDED to change the token status to &lt;code&gt;Redeemed&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC7439 Prevent Ticket Touting Interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; TokenStatus represent the token current status, only specific role can change status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenStatus&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Sold&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Resell&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Redeemed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 3&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Data signed by user&amp;#39;s private key or agent&amp;#39;s private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token status changing to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expireTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event due time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        TokenStatus tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; expireTime&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the token with the specified ID has been &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token has been &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token status has been &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Data signed by user&amp;#39;s private key or agent&amp;#39;s private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenStatusChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-variable&quot;&gt;        TokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to mint token with token status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `TokenStatusChanged` event if the token status is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The receiptent of token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Data signed by user&amp;#39;s private key or agent&amp;#39;s private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to change token status and can only be invoked by a specific role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `TokenStatusChanged` event if the token status is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token need to change status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Data signed by user&amp;#39;s private key or agent&amp;#39;s private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token status changing to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newExpireTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New event due time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        TokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newExpireTime&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0x15fbb306&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;What is the most crucial for ticketing agents, performers, and audiences?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For ticketing companies, selling out all tickets is crucial. Sometimes, to create a vibrant sales environment, ticketing companies may even collaborate with scalpers. This practice can be detrimental to both the audience and performers. To prevent such situations, there must be an open and transparent primary sales channel, as well as a fair secondary sales mechanism. In the &lt;code&gt;safeMint&lt;&#x2F;code&gt; function, which is a public function, we hope that everyone can mint tickets transparently at a listed price by themselves. At that time, &lt;code&gt;TokenInfo&lt;&#x2F;code&gt; adds a signature that only the buyer account or agent can resolve depending on the mechanism, to prove the ticket validity. And the token &lt;code&gt;status&lt;&#x2F;code&gt; is &lt;code&gt;Sold&lt;&#x2F;code&gt;. Despite this, we must also consider the pressures on ticketing companies. They aim to maximize the utility of every valid ticket, meaning selling out each one. In the traditional mechanism, ticketing companies only benefit from the initial sale, implying that they do not enjoy the excess profits from secondary sales. Therefore, we have designed a secondary sales process that is manageable for ticketing companies. In the &lt;code&gt;_beforeTokenTransfer()&lt;&#x2F;code&gt; function, you can see that it is an accessControl function, and only the &lt;code&gt;PARTNER_ROLE&lt;&#x2F;code&gt; &lt;code&gt;mint&lt;&#x2F;code&gt; or &lt;code&gt;burn&lt;&#x2F;code&gt; situation can transfer the ticket. The &lt;code&gt;PARTNER_ROLE&lt;&#x2F;code&gt; can be the ticket agency or a legal secondary ticket selling platform, which may be a state supervision or the ticket agency designated platform. To sustain the fair ticketing market, we cannot allow them to transfer tickets themselves, because we can’t distinguish whether the buyer is a scalper.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For performers or event holder, they aren&#x27;t willing to see bad news during ticket selling. A smooth ticketing process or no news that may damage their performers’ reputation is what they want. Other than that, what really matters is all the audience true fans who come. Tickets ending up in the hands of scalpers or entering a chaotic secondary market doesn&#x27;t really appeal to genuine fans. We believe performers wouldn&#x27;t be pleased with such a situation. Through the transparant mechanism, performers or event holder can control the real sales status at all times form cross-comparison of token mint amount and &lt;code&gt;TokenInfo&lt;&#x2F;code&gt;-&lt;code&gt;TokenStatus&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;enum TokenStatus {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Sold,    &#x2F;&#x2F; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Resell,  &#x2F;&#x2F; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Void,    &#x2F;&#x2F; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Redeemed &#x2F;&#x2F; 3&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;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For audiences, the only thing they need is to get a valid ticket. In the traditional mechanism,fans encounter many obstacles. At hot concerts, fans who try to snag tickets can run into some foes, like scalpers and ticketing companies. These scalpers are like pros, all organized and strategic in grabbing up tickets. Surprisingly, ticketing companies might actually team up with these scalpers. Or, they might just keep a bunch of freebies or VIP tickets to themselves. A transparent mechanism is equally important for the audiences.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;How to establish a healthy ticketing ecosystem?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Clear ticketing rules are key to making sure the supply and demand stay in balance.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;An open pricing system is a must to make sure consumers are protected.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Excellent liquidity. In the initial market, users can mint tickets themselves. If needed, purchased tickets can also be transferred in a transparent and open secondary market. Audiences who didn’t buy tickets during the initial sale can also confidently purchase tickets in a legal secondary market. The &lt;code&gt;changeState&lt;&#x2F;code&gt; function is to help the ticket have good liquidity. Only &lt;code&gt;PARTNER_ROLE&lt;&#x2F;code&gt; can change the ticket status. Once the sold ticket needs to be sold in the secondary market, it needs to ask the secondary market to help it change to resell status. The process of changing status is a kind of official verification of the secondary sale ticket. It is a protection mechanism to the second hand buyer.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;How to design a smooth ticketing process？&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Easy to buy&#x2F;sell. Audiences can buy ticket as mint NFT. This is a well-known practice.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Easy to refund. When something extreme happens and you need to cancel the show. Handling ticket refunds can be a straightforward process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Easy to redeem. Before the show, the ticket agency can verify the ticket by the signature to confirm if the audience is genuine. &lt;code&gt;TokenStatus&lt;&#x2F;code&gt; needs to be equal to &lt;code&gt;sold&lt;&#x2F;code&gt;, and &lt;code&gt;expireTime&lt;&#x2F;code&gt; can distinguish whether the audience has arrived at the correct session. After verification is passed, the ticket agency can change the &lt;code&gt;TokenStatus&lt;&#x2F;code&gt; to &lt;code&gt;Redeemed&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Normal Flow
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7439&#x2F;.&#x2F;assets&#x2F;normal.png&quot; alt=&quot;Alt text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Void Flow
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7439&#x2F;.&#x2F;assets&#x2F;void.png&quot; alt=&quot;Alt text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Resell Flow
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7439&#x2F;.&#x2F;assets&#x2F;resell.png&quot; alt=&quot;Alt text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; expectRevert&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@openzeppelin&#x2F;test-helpers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chai&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ERC7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; artifacts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;deployer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; userA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; userB&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; expireTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19999999&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; zeroHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  beforeEach&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ERC7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&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&gt;      from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deployer&lt;&#x2F;span&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;span&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;userA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deployer&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Should mint a token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tokenInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;userA&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;expireTime&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;expireTime&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should ordinary users cannot transfer successfully&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-entity z-name&quot;&gt;    expectRevert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;userA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userB&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userA&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC7439: You cannot transfer this NFT!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should partner can transfer successfully and chage the token info to resell status&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Resell&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; zeroHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;userA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;zeroHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Resell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;partner&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should partner can change the token status to void&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Void&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; zeroHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;zeroHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Void&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should partner can change the token status to redeemed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Redeemed&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; zeroHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;zeroHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Redeemed&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should partner can resell the token and change status from resell to sold&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Resell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; zeroHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;userA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Resell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;zeroHash&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    tokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; newSignature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x113hqb3ff45f5c6ec28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063w7h2f742f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newSignature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc7439&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;partner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userB&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partner&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tokenHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;newSignature&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&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;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If you need additional metadata, you can import ERC721URIStorage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; import &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;extensions&#x2F;ERC721URIStorage.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;access&#x2F;AccessControl.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;Counters.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC7439.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7439&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;AccessControl&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7439&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Counters&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Counters&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; PARTNER_ROLE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;PARTNER_ROLE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    Counters&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Counter &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;private&lt;&#x2F;span&gt;&lt;span&gt; _tokenIdCounter&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; expireTime&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; TokenInfo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; tokenInfo&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _expireTime&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;MyToken&amp;quot;, &amp;quot;MTK&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;DEFAULT_ADMIN_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;PARTNER_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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&gt;        expireTime &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _expireTime&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _tokenIdCounter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        _tokenIdCounter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;increment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; TokenStatus&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Sold&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expireTime&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenStatusChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; TokenStatus&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Sold&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; changeState&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        TokenStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newExpireTime&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;PARTNER_ROLE&lt;&#x2F;span&gt;&lt;span&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&gt;        tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newExpireTime&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenStatusChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenStatus&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            delete&lt;&#x2F;span&gt;&lt;span&gt; tokenInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If you import ERC721URIStorage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; delete _tokenURIs[tokenId];&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;AccessControl&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC7439&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;            super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;hasRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;PARTNER_ROLE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;                from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                &amp;quot;ERC7439: You cannot transfer this NFT!&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Parent-Governed Non-Fungible Tokens Nesting</title>
        <published>2023-07-26T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Cicada</name><uri>https://github.com/CicadaNCR</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7401/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6059-parent-governed-nestable-non-fungible-tokens/11914" />
        

        <id>https://wg-eips.ritovision.com/7401/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7401"
            label="ERC-7401" />
        

        
        

        
        <summary type="html">An interface for Non-Fungible Tokens Nesting with emphasis on parent token&#x27;s control over the relationship.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7401/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;❗️ &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;&quot;&gt;ERC-7401&lt;&#x2F;a&gt; supersedes &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;&quot;&gt;ERC-6059&lt;&#x2F;a&gt;.&lt;&#x2F;strong&gt; ❗️&lt;&#x2F;p&gt;
&lt;p&gt;The Parent-Governed NFT Nesting standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; by allowing for a new inter-NFT relationship and interaction.&lt;&#x2F;p&gt;
&lt;p&gt;At its core, the idea behind the proposal is simple: the owner of an NFT does not have to be an Externally Owned Account (EOA) or a smart contract, it can also be an NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The process of nesting an NFT into another is functionally identical to sending it to another user. The process of sending a token out of another one involves issuing a transaction from the account owning the parent token.&lt;&#x2F;p&gt;
&lt;p&gt;An NFT can be owned by a single other NFT, but can in turn have a number of NFTs that it owns. This proposal establishes the framework for the parent-child relationships of NFTs. A parent token is the one that owns another token. A child token is a token that is owned by another token. A token can be both a parent and child at the same time. Child tokens of a given token can be fully managed by the parent token&#x27;s owner, but can be proposed by anyone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-nestable-tokens.png&quot; alt=&quot;Nestable tokens&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The graph illustrates how a child token can also be a parent token, but both are still administered by the root parent token&#x27;s owner.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability for tokens to own other tokens allows for greater utility, usability and forward compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;In the four years since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; was published, the need for additional functionality has resulted in countless extensions. This ERC improves upon ERC-721 in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;#bundling&quot;&gt;Bundling&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;#collecting&quot;&gt;Collecting&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;#membership&quot;&gt;Membership&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;#delegation&quot;&gt;Delegation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal fixes the inconsistency in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;&quot;&gt;ERC-6059&lt;&#x2F;a&gt; interface specification, where interface ID doesn&#x27;t match the interface specified as the interface evolved during the proposal&#x27;s lifecycle, but one of the parameters was not added to it. The missing parameter is, however, present in the interface ID. Apart from this fix, this proposal is functionally equivalent to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;&quot;&gt;ERC-6059&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bundling&quot;&gt;Bundling&lt;&#x2F;h3&gt;
&lt;p&gt;One of the most frequent uses of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; is to disseminate the multimedia content that is tied to the tokens. In the event that someone wants to offer a bundle of NFTs from various collections, there is currently no easy way of bundling all of these together and handle their sale as a single transaction. This proposal introduces a standardized way of doing so. Nesting all of the tokens into a simple bundle and selling that bundle would transfer the control of all of the tokens to the buyer in a single transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collecting&quot;&gt;Collecting&lt;&#x2F;h3&gt;
&lt;p&gt;A lot of NFT consumers collect them based on countless criteria. Some aim for utility of the tokens, some for the uniqueness, some for the visual appeal, etc. There is no standardized way to group the NFTs tied to a specific account. By nesting NFTs based on their owner&#x27;s preference, this proposal introduces the ability to do it. The root parent token could represent a certain group of tokens and all of the children nested into it would belong to it.&lt;&#x2F;p&gt;
&lt;p&gt;The rise of soulbound, non-transferable, tokens, introduces another need for this proposal. Having a token with multiple soulbound traits (child tokens), allows for numerous use cases. One concrete example of this can be drawn from supply chains use case. A shipping container, represented by an NFT with its own traits, could have multiple child tokens denoting each leg of its journey.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;membership&quot;&gt;Membership&lt;&#x2F;h3&gt;
&lt;p&gt;A common utility attached to NFTs is a membership to a Decentralised Autonomous Organization (DAO) or to some other closed-access group. Some of these organizations and groups occasionally mint NFTs to the current holders of the membership NFTs. With the ability to nest mint a token into a token, such minting could be simplified, by simply minting the bonus NFT directly into the membership one.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delegation&quot;&gt;Delegation&lt;&#x2F;h3&gt;
&lt;p&gt;One of the core features of DAOs is voting and there are various approaches to it. One such mechanic is using fungible voting tokens where members can delegate their votes by sending these tokens to another member. Using this proposal, delegated voting could be handled by nesting your voting NFT into the one you are delegating your votes to and transferring it when the member no longer wishes to delegate their votes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-7401 Parent-Governed Nestable Non-Fungible Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-7401&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x42b0e56f.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7059&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The core struct of ownership.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `DirectOwner` struct is used to store information of the next immediate owner, be it the parent token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * an `ERC721Receiver` contract or an externally owned account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the token is not owned by an NFT, the `tokenId` MUST equal `0`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ownerAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the owner of the token. If the owner is another token, then the address MUST be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  the one of the parent token&amp;#39;s collection smart contract. If the owner is externally owned account, the address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST be the address of this account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DirectOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; ownerAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The core child token struct, holding the information about the child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contractAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Child&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; contractAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the token is being transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `tokenId` token is transferred from `from` to `to`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the previous immediate owner, which is a smart contract if the token was nested.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the new immediate owner, which is a smart contract if the token is being nested.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the previous parent token. If the token was not nested before, the value MUST be `0`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; toTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the new parent token. If the token is not being nested, the value MUST be `0`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NestTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a new token has been added to a given token&amp;#39;s pending children array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a child NFT is added to a token&amp;#39;s pending array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that received a new pending child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the proposed child token in the parent token&amp;#39;s pending children array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the proposed child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildProposed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a new child token was accepted by the parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a parent token accepts a token from its pending array, migrating it to the active array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that accepted a new child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the newly accepted child token in the parent token&amp;#39;s active children array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildAccepted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that all pending child tokens of a given token have been rejected.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token removes all child tokens from its pending array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that rejected all of the pending children&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AllChildrenRejected&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners a child token has been transferred from parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token transfers a child from itself, transferring ownership.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that transferred a child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of a child in the array from which it is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fromPending&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean value signifying whether the token was in the pending child tokens array (`true`) or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  in the active child tokens array (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; toZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean value signifying whether the token is being transferred to the `0x0` address (`true`) or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  not (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildTransferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromPending&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toZero&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the *root* owner of a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The *root* owner of the token is the top-level owner in the hierarchy which is not an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the token is owned by another NFT, it MUST recursively look up the parent&amp;#39;s root owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which the *root* owner has been retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The *root* owner of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the immediate owner of the given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the immediate owner is another token, the address returned, MUST be the one of the parent token&amp;#39;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  collection smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which the direct owner is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the given token&amp;#39;s owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the parent token. MUST be `0` if the owner is not an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean value signifying whether the owner is an NFT or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; directOwnerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        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 class=&quot;z-support&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 class=&quot;z-support&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 class=&quot;z-support&quot;&gt;            bool&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to burn a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When a token is burned, all of its child tokens are recursively burned as well.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When specifying the maximum recursive burns, the execution MUST be reverted if there are more children to be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  burned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Setting the `maxRecursiveBurn` value to 0 SHOULD only attempt to burn the specified token and MUST revert if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  there are any child tokens present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; maxRecursiveBurns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maximum number of tokens to recursively burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of recursively burned children&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; maxRecursiveBurns&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to add a child token to a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This adds the child token into the given parent token&amp;#39;s pending child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The destination token MUST NOT be a child token of the token being transferred or one of its downstream&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MUST NOT be called directly. It MUST only be called from an instance of `IERC7059` as part of a &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        `nestTransfer` or `transferChild` to an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `directOwnerOf` on the child contract MUST resolve to the called contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - the pending array of the parent contract MUST not be full.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token to receive the new child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the new proposed child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to accept a pending child token for a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This moves the child token from parent token&amp;#39;s pending child tokens array into the active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the child token is being accepted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token to accept in the pending children array of a given token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract of the child token expected to be at the specified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token expected to be located at the specified index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to reject all pending children of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Removes the children from the pending array mapping.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The children&amp;#39;s ownership structures are not updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `parentId` MUST exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to reject all of the pending tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maximum number of expected children to reject, used to prevent from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  rejecting children which arrive just before this operation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; rejectAllChildren&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to transfer a child token from a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST remove the child from the parent&amp;#39;s active or pending children.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When transferring a child token, the owner of the token MUST be set to `to`, or not updated in the event of `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  being the `0x0` address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token from which the child token is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to which to transfer the token to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to receive this child token (MUST be 0 if the destination is not a token)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of a token we are transferring, in the array it belongs to (can be either active array or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  pending array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in its own collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean value indicating whether the child token being transferred is in the pending array of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  parent token (`true`) or in the active array (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, sent in call to `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the active child tokens of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns array of Child structs existing for parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to retrieve the active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of Child structs containing the parent token&amp;#39;s active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childrenOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the pending child tokens of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns array of pending Child structs existing for given parent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to retrieve the pending child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of Child structs containing the parent token&amp;#39;s pending child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pendingChildrenOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve a specific active child token for a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a single Child struct locating at `index` of parent token&amp;#39;s active child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the child is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token in the parent token&amp;#39;s active child tokens array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A Child struct containing data about the specified child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve a specific pending child token from a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a single Child struct locating at `index` of parent token&amp;#39;s active child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the pending child token is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token in the parent token&amp;#39;s pending child tokens array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A Child struct containing data about the specified child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pendingChildOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to transfer the token into another token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The destination token MUST NOT be a child token of the token being transferred or one of its downstream&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the direct owner of the token to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the receiving token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to receive the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nestTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ID MUST never be a &lt;code&gt;0&lt;&#x2F;code&gt; value, as this proposal uses &lt;code&gt;0&lt;&#x2F;code&gt; values do signify that the token&#x2F;destination is not an NFT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;How to name the proposal?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
In an effort to provide as much information about the proposal we identified the most important aspect of the proposal; the parent centered control over nesting. The child token&#x27;s role is only to be able to be &lt;code&gt;Nestable&lt;&#x2F;code&gt; and support a token owning it. This is how we landed on the &lt;code&gt;Parent-Centered&lt;&#x2F;code&gt; part of the title.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is automatically accepting a child using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; permit-style signatures not a part of this proposal?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
For consistency. This proposal extends ERC-721 which already uses 1 transaction for approving operations with tokens. It would be inconsistent to have this and also support signing messages for operations with assets.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why use indexes?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
To reduce the gas consumption. If the token ID was used to find which token to accept or reject, iteration over arrays would be required and the cost of the operation would depend on the size of the active or pending children arrays. With the index, the cost is fixed. Lists of active and pending children per token need to be maintained, since methods to get them are part of the proposed interface.&lt;br &#x2F;&gt;
To avoid race conditions in which the index of a token changes, the expected token ID as well as the expected token&#x27;s collection smart contract is included in operations requiring token index, to verify that the token being accessed using the index is the expected one.&lt;br &#x2F;&gt;
Implementation that would internally keep track of indices using mapping was attempted. The minimum cost of accepting a child token was increased by over 20% and the cost of minting has increased by over 15%. We concluded that it is not necessary for this proposal and can be implemented as an extension for use cases willing to accept the increased transaction cost this incurs. In the sample implementation provided, there are several hooks which make this possible.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is the pending children array limited instead of supporting pagination?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The pending child tokens array is not meant to be a buffer to collect the tokens that the root owner of the parent token wants to keep, but not enough to promote them to active children. It is meant to be an easily traversable list of child token candidates and should be regularly maintained; by either accepting or rejecting proposed child tokens. There is also no need for the pending child tokens array to be unbounded, because active child tokens array is.&lt;br &#x2F;&gt;
Another benefit of having bounded child tokens array is to guard against spam and griefing. As minting malicious or spam tokens could be relatively easy and low-cost, the bounded pending array assures that all of the tokens in it are easy to identify and that legitimate tokens are not lost in a flood of spam tokens, if one occurs.&lt;br &#x2F;&gt;
A consideration tied to this issue was also how to make sure, that a legitimate token is not accidentally rejected when clearing the pending child tokens array. We added the maximum pending children to reject argument to the clear pending child tokens array call. This assures that only the intended number of pending child tokens is rejected and if a new token is added to the pending child tokens array during the course of preparing such call and executing it, the clearing of this array SHOULD result in a reverted transaction.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we allow tokens to be nested into one of its children?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The proposal enforces that a parent token can&#x27;t be nested into one of its child token, or downstream child tokens for that matter. A parent token and its children are all managed by the parent token&#x27;s root owner. This means that if a token would be nested into one of its children, this would create the ownership loop and none of the tokens within the loop could be managed anymore.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is there not a &quot;safe&quot; nest transfer method?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;code&gt;nestTransfer&lt;&#x2F;code&gt; is always &quot;safe&quot; since it MUST check for &lt;code&gt;IERC7059&lt;&#x2F;code&gt; compatibility on the destination.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How does this proposal differ from the other proposals trying to address a similar problem?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
This interface allows for tokens to both be sent to and receive other tokens. The propose-accept and parent governed patterns allow for a more secure use. The backward compatibility is only added for ERC-721, allowing for a simpler interface. The proposal also allows for different collections to inter-operate, meaning that nesting is not locked to a single smart contract, but can be executed between completely separate NFT collections.&lt;br &#x2F;&gt;
Additionally this proposal addresses the inconsistencies between &lt;code&gt;interfaceId&lt;&#x2F;code&gt;, interface specification and example implementation of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;&quot;&gt;ERC-6059&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;propose-commit-pattern-for-child-token-management&quot;&gt;Propose-Commit pattern for child token management&lt;&#x2F;h3&gt;
&lt;p&gt;Adding child tokens to a parent token MUST be done in the form of propose-commit pattern to allow for limited mutability by a 3rd party. When adding a child token to a parent token, it is first placed in a &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; array, and MUST be migrated to the &lt;em&gt;&quot;Active&quot;&lt;&#x2F;em&gt; array by the parent token&#x27;s root owner. The &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; child tokens array SHOULD be limited to 128 slots to prevent spam and griefing.&lt;&#x2F;p&gt;
&lt;p&gt;The limitation that only the root owner can accept the child tokens also introduces a trust inherent to the proposal. This ensures that the root owner of the token has full control over the token. No one can force the user to accept a child if they don&#x27;t want to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parent-governed-pattern&quot;&gt;Parent Governed pattern&lt;&#x2F;h3&gt;
&lt;p&gt;The parent NFT of a nested token and the parent&#x27;s root owner are in all aspects the true owners of it. Once you send a token to another one you give up ownership.&lt;&#x2F;p&gt;
&lt;p&gt;We continue to use ERC-721&#x27;s &lt;code&gt;ownerOf&lt;&#x2F;code&gt; functionality which will now recursively look up through parents until it finds an address which is not an NFT, this is referred to as the &lt;em&gt;root owner&lt;&#x2F;em&gt;. Additionally we provide the &lt;code&gt;directOwnerOf&lt;&#x2F;code&gt; which returns the most immediate owner of a token using 3 values: the owner address, the tokenId which MUST be 0 if the direct owner is not an NFT, and a flag indicating whether or not the parent is an NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The root owner or an approved party MUST be able to do the following operations on children: &lt;code&gt;acceptChild&lt;&#x2F;code&gt;, &lt;code&gt;rejectAllChildren&lt;&#x2F;code&gt; and &lt;code&gt;transferChild&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The root owner or an approved party MUST also be allowed to do these operations only when token is not owned by an NFT: &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;, &lt;code&gt;nestTransferFrom&lt;&#x2F;code&gt;, &lt;code&gt;burn&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the token is owned by an NFT, only the parent NFT itself MUST be allowed to execute the operations listed above. Transfers MUST be done from the parent token, using &lt;code&gt;transferChild&lt;&#x2F;code&gt;, this method in turn SHOULD call &lt;code&gt;nestTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; in the child token&#x27;s smart contract, according to whether the destination is an NFT or not. For burning, tokens must first be transferred to an EOA and then burned.&lt;&#x2F;p&gt;
&lt;p&gt;We add this restriction to prevent inconsistencies on parent contracts, since only the &lt;code&gt;transferChild&lt;&#x2F;code&gt; method takes care of removing the child from the parent when it is being transferred out of it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;child-token-management&quot;&gt;Child token management&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal introduces a number of child token management functions. In addition to the permissioned migration from &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; to &lt;em&gt;&quot;Active&quot;&lt;&#x2F;em&gt; child tokens array, the main token management function from this proposal is the &lt;code&gt;transferChild&lt;&#x2F;code&gt; function. The following state transitions of a child token are available with it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reject child token&lt;&#x2F;li&gt;
&lt;li&gt;Abandon child token&lt;&#x2F;li&gt;
&lt;li&gt;Unnest child token&lt;&#x2F;li&gt;
&lt;li&gt;Transfer the child token to an EOA or an &lt;code&gt;ERC721Receiver&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Transfer the child token into a new parent token&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To better understand how these state transitions are achieved, we have to look at the available parameters passed to &lt;code&gt;transferChild&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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;Based on the desired state transitions, the values of these parameters have to be set accordingly (any parameters not set in the following examples depend on the child token being managed):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reject child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-reject-child.png&quot; alt=&quot;Reject child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Abandon child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-abandon-child.png&quot; alt=&quot;Abandon child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Unnest child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-unnest-child.png&quot; alt=&quot;Unnest child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transfer the child token to an EOA or an &lt;code&gt;ERC721Receiver&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-transfer-child-to-eoa.png&quot; alt=&quot;Transfer child token to EOA&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transfer the child token into a new parent token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-7401-transfer-child-to-token.png&quot; alt=&quot;Transfer child token to parent token&quot; &#x2F;&gt;&lt;br &#x2F;&gt;
This state change places the token in the pending array of the new parent token. The child token still needs to be accepted by the new parent token&#x27;s root owner in order to be placed into the active array of that token.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Nestable token standard has been made compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; in order to take advantage of the robust tooling available for implementations of ERC-721 and to ensure compatibility with existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;The only incompatibility with ERC-721 is that Nestable tokens cannot use a token ID of 0.&lt;&#x2F;p&gt;
&lt;p&gt;There is some differentiation of how the &lt;code&gt;ownerOf&lt;&#x2F;code&gt; method behaves compared to ERC-721. The &lt;code&gt;ownerOf&lt;&#x2F;code&gt; method will now recursively look up through parent tokens until it finds an address that is not an NFT; this is referred to as the &lt;em&gt;root owner&lt;&#x2F;em&gt;. Additionally, we provide the &lt;code&gt;directOwnerOf&lt;&#x2F;code&gt;, which returns the most immediate owner of a token using 3 values: the owner address, the &lt;code&gt;tokenId&lt;&#x2F;code&gt;, which MUST be 0 if the direct owner is not an NFT, and a flag indicating whether or not the parent is an NFT. In case the token is owned by an EoA or an ERC-721 Receiver, the &lt;code&gt;ownerOf&lt;&#x2F;code&gt; method will behave the same as in ERC-721.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;test&#x2F;nestable.ts&quot;&gt;&lt;code&gt;nestable.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-7401&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7401&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;NestableToken.sol&quot;&gt;&lt;code&gt;NestableToken.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; apply: hidden logic may be present in any of the functions, including burn, add child, accept child, and more.&lt;&#x2F;p&gt;
&lt;p&gt;Since the current owner of the token is allowed to manage the token, there is a possibility that after the parent token is listed for sale, the seller might remove a child token just before before the sale and thus the buyer would not receive the expected child token. This is a risk that is inherent to the design of this standard. Marketplaces should take this into account and provide a way to verify the expected child tokens are present when the parent token is being sold or to guard against such a malicious behaviour in another way.&lt;&#x2F;p&gt;
&lt;p&gt;It is worth noting that &lt;code&gt;balanceOf&lt;&#x2F;code&gt; method only accounts for immediate tokens owned by the address; the tokens that are nested into a token owned by this address will not be reflected in this value as the recursive lookup needed in order to calculate this value is potentially too deep and might break the method.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Public Non-Fungible Tokens Emote Repository</title>
        <published>2023-07-26T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7409/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6381-emotable-extension-for-non-fungible-tokens/12710" />
        

        <id>https://wg-eips.ritovision.com/7409/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7409"
            label="ERC-7409" />
        

        
        

        
        <summary type="html">React to any Non-Fungible Tokens using Unicode emojis.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7409/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;❗️ &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;&quot;&gt;ERC-7409&lt;&#x2F;a&gt; supersedes &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;&quot;&gt;ERC-6381&lt;&#x2F;a&gt;.&lt;&#x2F;strong&gt; ❗️&lt;&#x2F;p&gt;
&lt;p&gt;The Public Non-Fungible Tokens Emote Repository standard provides an enhanced interactive utility for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; by allowing NFTs to be emoted at.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal introduces the ability to react to NFTs using Unicode standardized emoji in a public non-gated repository smart contract that is accessible at the same address in all of the networks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability for anyone to interact with an NFT introduces an interactive aspect to owning an NFT and unlocks feedback-based NFT mechanics.&lt;&#x2F;p&gt;
&lt;p&gt;This ERC introduces new utilities for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; based tokens in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;#interactivity&quot;&gt;Interactivity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;#feedback-based-evolution&quot;&gt;Feedback based evolution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;#valuation&quot;&gt;Valuation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal fixes the compatibility issue in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;&quot;&gt;ERC-6381&lt;&#x2F;a&gt; interface specification, where emojis are represented using &lt;code&gt;bytes4&lt;&#x2F;code&gt; values. The introduction of variation flags and emoji skin tones has rendered the &lt;code&gt;bytes4&lt;&#x2F;code&gt; namespace insufficient for representing all possible emojis, so the new standard used &lt;code&gt;string&lt;&#x2F;code&gt; instead. Apart from this fix, this proposal is functionally equivalent to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;&quot;&gt;ERC-6381&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interactivity&quot;&gt;Interactivity&lt;&#x2F;h3&gt;
&lt;p&gt;The ability to emote on an NFT introduces the aspect of interactivity to owning an NFT. This can either reflect the admiration for the emoter (person emoting to an NFT) or can be a result of a certain action performed by the token&#x27;s owner. Accumulating emotes on a token can increase its uniqueness and&#x2F;or value.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;feedback-based-evolution&quot;&gt;Feedback based evolution&lt;&#x2F;h3&gt;
&lt;p&gt;Standardized on-chain reactions to NFTs allow for feedback based evolution.&lt;&#x2F;p&gt;
&lt;p&gt;Current solutions are either proprietary or off-chain and therefore subject to manipulation and distrust. Having the ability to track the interaction on-chain allows for trust and objective evaluation of a given token. Designing the tokens to evolve when certain emote thresholds are met incentivizes interaction with the token collection.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;valuation&quot;&gt;Valuation&lt;&#x2F;h3&gt;
&lt;p&gt;Current NFT market heavily relies on previous values the token has been sold for, the lowest price of the listed token and the scarcity data provided by the marketplace. There is no real time indication of admiration or desirability of a specific token. Having the ability for users to emote to the tokens adds the possibility of potential buyers and sellers gauging the value of the token based on the impressions the token has collected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7409 Emotable Extension for Non-Fungible Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-7409&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x1b3327ab.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7409&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;is IERC165&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the token with the specified ID has been emoted to or that the reaction has been revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event MUST only be emitted if the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that emoted or revoked the reaction to the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract containing the token being emoted to or having the reaction revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; on&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether the token was emoted to (`true`) or if the reaction has been revoked (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Emoted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; on&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the number of emotes for a specific emoji on a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection containing the token being checked for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to check for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of emotes with the emoji on the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; emoteCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the number of emotes for a specific emoji on a set of tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being checked for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens to check for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; An&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of numbers of emotes with the emoji on the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkEmoteCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the information on whether the specified address has used a specific emoji on a specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account we are checking for a reaction to a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract containing the token being checked for emoji reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being checked for emoji reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ASCII emoji code being checked for reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; boolean value indicating whether the `emoter` has used the `emoji` on the token (`true`) or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasEmoterUsedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the information on whether the specified addresses have used specific emojis on specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the accounts we are checking for reactions to tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collection smart contracts containing the tokens being checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  for emoji reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being checked for emoji reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of the ASCII emoji codes being checked for reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; An&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of boolean values indicating whether the `emoter`s has used the `emoji`s on the tokens (`true`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  or not (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; haveEmotersUsedEmotes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the message to be signed by the `emoter` in order for the reaction to be submitted by someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the collection smart contract containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; message to be signed by the `emoter` in order for the reaction to be submitted by someone else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; prepareMessageToPresignEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadline&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get multiple messages to be signed by the `emoter` in order for the reaction to be submitted by someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collection smart contracts containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of UNIX timestamps of the deadlines for the signatures to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of messages to be signed by the `emoter` in order for the reaction to be submitted by someone else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkPrepareMessagesToPresignEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadlines&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; emote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on multiple tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on someone else&amp;#39;s behalf.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the `deadline` has passed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the recovered address is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that presigned the emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the collection smart contract containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IDs of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `v` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `r` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `s` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; presignedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to bulk emote or undo an emote on someone else&amp;#39;s behalf.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the `deadline` has passed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the recovered address is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the accounts that presigned the emotes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `v` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `r` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `s` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkPresignedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;message-format-for-presigned-emotes&quot;&gt;Message format for presigned emotes&lt;&#x2F;h3&gt;
&lt;p&gt;The message to be signed by the &lt;code&gt;emoter&lt;&#x2F;code&gt; in order for the reaction to be submitted by someone else is formatted as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&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&gt;            emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            deadline&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The values passed when generating the message to be signed are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; - The domain separator of the Emotable repository smart contract&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;collection&lt;&#x2F;code&gt; - Address of the collection containing the token being emoted at&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt; - ID of the token being emoted&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;emoji&lt;&#x2F;code&gt; - Unicode identifier of the emoji&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;state&lt;&#x2F;code&gt; - Boolean value signifying whether to emote (&lt;code&gt;true&lt;&#x2F;code&gt;) or undo (&lt;code&gt;false&lt;&#x2F;code&gt;) emote&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;deadline&lt;&#x2F;code&gt; - UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; is generated as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;ERC-7409: Public Non-Fungible Token Emote Repository&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 class=&quot;z-string&quot;&gt;            &amp;quot;1&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 class=&quot;z-variable z-language&quot;&gt;            block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each chain, that the Emotable repository smart contract is deployed on, will have a different &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; value due to chain IDs being different.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pre-determined-address-of-the-emotable-repository&quot;&gt;Pre-determined address of the Emotable repository&lt;&#x2F;h3&gt;
&lt;p&gt;The address of the Emotable repository smart contract is designed to resemble the function it serves. It starts with &lt;code&gt;0x3110735&lt;&#x2F;code&gt; which is the abstract representation of &lt;code&gt;EMOTES&lt;&#x2F;code&gt;. The address is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x3110735F0b8e71455bAe1356a33e428843bCb9A1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Does the proposal support custom emotes or only the Unicode specified ones?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The proposal only accepts the Unicode identifier which is a &lt;code&gt;string&lt;&#x2F;code&gt; value. This means that while we encourage implementers to add the reactions using standardized emojis, the values not covered by the Unicode standard can be used for custom emotes. The only drawback being that the interface displaying the reactions will have to know what kind of image to render and such additions will probably be limited to the interface or marketplace in which they were made.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should the proposal use emojis to relay the impressions of NFTs or some other method?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The impressions could have been done using user-supplied strings or numeric values, yet we decided to use emojis since they are a well established mean of relaying impressions and emotions.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should the proposal establish an emotable extension or a common-good repository?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Initially we set out to create an emotable extension to be used with any ERC-721 compliant tokens. However, we realized that the proposal would be more useful if it was a common-good repository of emotable tokens. This way, the tokens that can be reacted to are not only the new ones but also the old ones that have been around since before the proposal.&lt;br &#x2F;&gt;
In line with this decision, we decided to calculate a deterministic address for the repository smart contract. This way, the repository can be used by any NFT collection without the need to search for the address on the given chain.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we include only single-action operations, only multi-action operations, or both?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
We&#x27;ve considered including only single-action operations, where the user is only able to react with a single emoji to a single token, but we decided to include both single-action and multi-action operations. This way, the users can choose whether they want to emote or undo emote on a single token or on multiple tokens at once.&lt;br &#x2F;&gt;
This decision was made for the long-term viability of the proposal. Based on the gas cost of the network and the number of tokens in the collection, the user can choose the most cost-effective way of emoting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we add the ability to emote on someone else&#x27;s behalf?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
While we did not intend to add this as part of the proposal when drafting it, we realized that it would be a useful feature for it. This way, the users can emote on behalf of someone else, for example, if they are not able to do it themselves or if the emote is earned through an off-chain activity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How do we ensure that emoting on someone else&#x27;s behalf is legitimate?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
We could add delegates to the proposal; when a user delegates their right to emote to someone else, the delegate can emote on their behalf. However, this would add a lot of complexity and additional logic to the proposal.&lt;br &#x2F;&gt;
Using ECDSA signatures, we can ensure that the user has given their consent to emote on their behalf. This way, the user can sign a message with the parameters of the emote and the signature can be submitted by someone else.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we add chain ID as a parameter when reacting to a token?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
During the course of discussion of the proposal, a suggestion arose that we could add chain ID as a parameter when reacting to a token. This would allow the users to emote on the token of one chain on another chain.&lt;br &#x2F;&gt;
We decided against this as we feel that additional parameter would rarely be used and would add additional cost to the reaction transactions. If the collection smart contract wants to utilize on-chain emotes to tokens they contain, they require the reactions to be recorded on the same chain. Marketplaces and wallets integrating this proposal will rely on reactions to reside in the same chain as well, because if chain ID parameter was supported this would mean that they would need to query the repository smart contract on all of the chains the repository is deployed in order to get the reactions for a given token.&lt;br &#x2F;&gt;
Additionally, if the collection creator wants users to record their reactions on a different chain, they can still direct the users to do just that. The repository does not validate the existence of the token being reacted to, which in theory means that you can react to non-existent token or to a token that does not exist yet. The likelihood of a different collection existing at the same address on another chain is significantly low, so the users can react using the collection&#x27;s address on another chain and it is very unlikely that they will unintentionally react to another collection&#x27;s token.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we use &lt;code&gt;bytes4&lt;&#x2F;code&gt; or &lt;code&gt;strings&lt;&#x2F;code&gt; to represent emotes?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Initially the proposal used &lt;code&gt;bytes4&lt;&#x2F;code&gt;. This was due to the assumption that all of the emojis use UTF-4 encoding, which is not the case.&lt;br &#x2F;&gt;
The emojis usually use up to 8 bytes, but the personalized emojis with skin tones use much more. This is why we decided to use &lt;code&gt;strings&lt;&#x2F;code&gt; to represent the emotes. This allows the repository to be forward compatible with any future emojis that might be added to the Unicode standard.&lt;br &#x2F;&gt;
This is how this proposal fixes the forward compatibility issue of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;&quot;&gt;ERC-6381&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Emote repository standard is fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and with the robust tooling available for implementations of ERC-721 as well as with the existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;.&#x2F;assets&#x2F;test&#x2F;emotableRepository.ts&quot;&gt;&lt;code&gt;emotableRepository.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-7409&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7409&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;EmotableRepository.sol&quot;&gt;&lt;code&gt;EmotableRepository.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The proposal does not envision handling any form of assets from the user, so the assets should not be at risk when interacting with an Emote repository.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to use ECDSA signatures to emote on someone else&#x27;s behalf introduces the risk of a replay attack, which the format of the message to be signed guards against. The &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; used in the message to be signed is unique to the repository smart contract of the chain it is deployed on. This means that the signature is invalid on any other chain and the Emote repositories deployed on them should revert the operation if a replay attack is attempted.&lt;&#x2F;p&gt;
&lt;p&gt;Another thing to consider is the ability of presigned message reuse. Since the message includes the signature validity deadline, the message can be reused any number of times before the deadline is reached. The proposal only allows for a single reaction with a given emoji to a specific token to be active, so the presigned message can not be abused to increase the reaction count on the token. However, if the service using the repository relies on the ability to revoke the reaction after certain actions, a valid presigned message can be used to re-react to the token. We suggest that the services using the repository in conjunction with presigned messages use deadlines that invalidate presigned messages after a reasonably short period of time.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Non-Fungible Token Roles</title>
        <published>2023-07-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ernani São Thiago</name><uri>https://github.com/ernanirst</uri>
	</author>
	
	<author>
		<name>Daniel Lima</name><uri>https://github.com/karacurt</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7432/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7432-non-fungible-token-roles/15298" />
        

        <id>https://wg-eips.ritovision.com/7432/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7432"
            label="ERC-7432" />
        

        
        

        
        <summary type="html">Role Management for NFTs. Enables accounts to share the utility of NFTs via expirable role assignments.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7432/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard introduces role management for NFTs. Each role assignment is associated with a single NFT and expires
automatically at a given timestamp. Roles are defined as &lt;code&gt;bytes32&lt;&#x2F;code&gt; and feature a custom &lt;code&gt;data&lt;&#x2F;code&gt; field of arbitrary size
to allow customization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The NFT Roles interface aims to establish a standard for role management in NFTs. Tracking on-chain roles enables
decentralized applications (dApps) to implement access control for privileged actions, e.g., minting tokens with a role
(airdrop claim rights).&lt;&#x2F;p&gt;
&lt;p&gt;NFT roles can be deeply integrated with dApps to create a utility-sharing mechanism. A good example is in digital real
estate. A user can create a digital property NFT and grant a &lt;code&gt;keccak256(&quot;PropertyManager()&quot;)&lt;&#x2F;code&gt; role to another user,
allowing them to delegate specific utility without compromising ownership. The same user could also grant a
&lt;code&gt;keccak256(&quot;PropertyTenant(uint256)&quot;)&lt;&#x2F;code&gt; role to other users, allowing the recipient to access and interact with the
digital property.&lt;&#x2F;p&gt;
&lt;p&gt;There are also interesting use cases in decentralized finance (DeFi). Insurance policies could be issued as NFTs, and
the beneficiaries, insured, and insurer could all be on-chain roles tracked using this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,
&quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC-2119 and RFC-8174.&lt;&#x2F;p&gt;
&lt;p&gt;Compliant contracts MUST implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7432 Non-Fungible Token Roles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-7432&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xd00ca5cf.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7432&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Role&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; roleId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt; expirationDate&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; revocable&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Events *&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an NFT is locked (deposited or frozen).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner of the NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenLocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a role is granted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user assigning the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _recipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user receiving the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _expirationDate&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The expiration date of the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _revocable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Whether the role is revocable or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Any additional data about the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleGranted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _expirationDate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _revocable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _data&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a role is revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an NFT is unlocked (withdrawn or unfrozen).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The original owner of the NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUnlocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a user is approved to manage roles on behalf of another user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user approved to grant and revoke roles.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _isApproved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval status.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RoleApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _isApproved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; External Functions *&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Grants a role to a user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts if sender is not approved or the NFT owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _role&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role attributes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; grantRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Role&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _role&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revokes a role from a user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts if sender is not approved or the original owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unlocks NFT (transfer back to original owner or unfreeze it).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts if sender is not approved or the original owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unlockToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approves operator to grant and revoke roles on behalf of another user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user approved to grant and revoke roles.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval status.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setRoleApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; View Functions *&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the original owner of the NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the recipient of an NFT role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; recipient_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user that received the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; recipientOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _roleId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the custom data of a role assignment.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The custom data of the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; roleData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _roleId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the expiration date of a role assignment.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expirationDate_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The expiration date of the role.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; roleExpirationDate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _roleId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expirationDate_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies whether the role is revocable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _roleId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The role identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; revocable_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Whether the role is revocable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isRoleRevocable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _roleId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; revocable_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies if the owner approved the operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user that approved the operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user that can grant and revoke roles.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the operator is approved.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isRoleApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;metadata-extension&quot;&gt;Metadata Extension&lt;&#x2F;h3&gt;
&lt;p&gt;The Roles Metadata extension extends the traditional JSON-based metadata schema of NFTs. Therefore, DApps supporting
this feature MUST also implement the metadata extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. This extension is &lt;strong&gt;optional&lt;&#x2F;strong&gt; and allows
developers to provide additional information for roles.&lt;&#x2F;p&gt;
&lt;p&gt;Updated Metadata Schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&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&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Existing NFT Metadata *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional fields for Roles *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the role&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Human-readable name of the role&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the role&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Human-readable name of the argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Solidity type, e.g., uint256 or address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;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 following JSON is an example of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7432&#x2F;&quot;&gt;ERC-7432&lt;&#x2F;a&gt; Metadata:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ... Existing NFT Metadata&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256(&amp;quot;PropertyManager()&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x76be0ffb73d8cd9e8fa76c28632ebbc3865a8ec7a0b6acab6ac589a1c88dd301&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Property Manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The manager of the property is responsible for furnishing it and ensuring its good condition.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256(&amp;quot;PropertyTenant(uint256)&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x17dfc8ea82661b71bd62ce0bd9db3858dd8f3e8ab9799d6ab468ec64f1be21a5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Property Tenant&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The tenant of the property is responsible for paying the rent and keeping the property in good condition.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;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 &lt;code&gt;roles&lt;&#x2F;code&gt; array properties are SUGGESTED, and developers should add any other relevant information as necessary (e.g.,
an image for the role). It&#x27;s also important to highlight the importance of the &lt;code&gt;inputs&lt;&#x2F;code&gt; property. This field describes
the parameters that should be encoded and passed to the &lt;code&gt;grantRole&lt;&#x2F;code&gt; function. It&#x27;s RECOMMENDED to use the properties
&lt;code&gt;type&lt;&#x2F;code&gt; and &lt;code&gt;components&lt;&#x2F;code&gt; defined on the Solidity ABI Specification, where &lt;code&gt;type&lt;&#x2F;code&gt; is the canonical type of the parameter,
and &lt;code&gt;components&lt;&#x2F;code&gt; is used for complex tuple types.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Compliant contracts MUST implement the &lt;code&gt;IERC7432&lt;&#x2F;code&gt; interface.&lt;&#x2F;li&gt;
&lt;li&gt;A role is represented by a &lt;code&gt;bytes32&lt;&#x2F;code&gt;, and it&#x27;s RECOMMENDED to use the &lt;code&gt;keccak256&lt;&#x2F;code&gt; of the role&#x27;s name with its inputs:
&lt;code&gt;bytes32 roleId = keccak256(&quot;RoleName(input_type)&quot;)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;grantRole&lt;&#x2F;code&gt; function MUST revert if the &lt;code&gt;expirationDate&lt;&#x2F;code&gt; is in the past or if the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is not approved to
grant roles on behalf of the NFT owner. It MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;In addition to emitting the &lt;code&gt;RoleGranted&lt;&#x2F;code&gt; event, the &lt;code&gt;grantRole&lt;&#x2F;code&gt; function MUST emit a &lt;code&gt;TokenLocked&lt;&#x2F;code&gt; event if the token
is frozen or transferred to an escrow account.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;revokeRole&lt;&#x2F;code&gt; function MUST revert if the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is not approved to revoke roles on behalf of the original
NFT owner or the &lt;code&gt;recipient&lt;&#x2F;code&gt;. It MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;revocable&lt;&#x2F;code&gt; is false, only the &lt;code&gt;recipient&lt;&#x2F;code&gt; can revoke the role. If &lt;code&gt;revocable&lt;&#x2F;code&gt; is true, both the &lt;code&gt;recipient&lt;&#x2F;code&gt; and
the original NFT owner can revoke the role.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;unlockToken&lt;&#x2F;code&gt; function MUST revert if the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is not approved, or if there is at least one non-revocable
role not expired. It MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;setRoleApprovalForAll&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;ownerOf&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and MUST return the address of the original owner of
the NFT.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;recipientOf&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and MUST return the address of the account that
received the role.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;roleData&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and MUST return the encoded data passed to the
&lt;code&gt;grantRole&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;roleExpirationDate&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and MUST return the expiration date of a
given role.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;isRoleRevocable&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and MUST return whether the role is revocable.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;isRoleApprovedForAll&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;, and SHOULD only return &lt;code&gt;true&lt;&#x2F;code&gt; if the
&lt;code&gt;_operator&lt;&#x2F;code&gt; is approved to grant and revoke roles on behalf of the original NFT owner.&lt;&#x2F;li&gt;
&lt;li&gt;Compliant contracts SHOULD implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7432&#x2F;&quot;&gt;ERC-7432&lt;&#x2F;a&gt; IS NOT an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. The main reason behind this decision is to
enable it to be implemented externally or on the same contract as the NFT, allowing dApps to implement roles with
immutable assets. This standard covers many crucial features, such as automatic expiration and custom data, but perhaps
the most important one is its flexibility in implementation. ERC-7432 can be implemented in many ways, and for this
reason, the neutral term &quot;lock&quot; is employed. This term can refer to an NFT being frozen (preventing transfers until
roles expire) or deposited in an escrow contract. Developers should decide which implementation to use based on their
use cases.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;automatic-expiration&quot;&gt;Automatic Expiration&lt;&#x2F;h3&gt;
&lt;p&gt;Automatic expiration is implemented via the &lt;code&gt;grantRole&lt;&#x2F;code&gt; and &lt;code&gt;roleExpirationDate&lt;&#x2F;code&gt; functions. &lt;code&gt;grantRole&lt;&#x2F;code&gt; is responsible
for setting the expiration date, and &lt;code&gt;roleExpirationDate&lt;&#x2F;code&gt; allow developers to check whether the role is expired. Since
&lt;code&gt;uint256&lt;&#x2F;code&gt; is not natively supported by most programming languages, dates are represented as &lt;code&gt;uint64&lt;&#x2F;code&gt; on this standard.
The maximum UNIX timestamp represented by a &lt;code&gt;uint64&lt;&#x2F;code&gt; is about the year &lt;code&gt;584,942,417,355&lt;&#x2F;code&gt;, which should be enough to be
considered &quot;permanent&quot;. For this reason, it&#x27;s recommended using &lt;code&gt;type(uint64).max&lt;&#x2F;code&gt; to support use cases that require a
role never to expire.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;revocable-roles&quot;&gt;Revocable Roles&lt;&#x2F;h3&gt;
&lt;p&gt;In certain scenarios, the original owner of the NFT may need to revoke a role before its expiration date, while in
others, the recipient may require assurance that the role cannot be revoked. The &lt;code&gt;revocable&lt;&#x2F;code&gt; parameter was introduced
to the &lt;code&gt;grantRole&lt;&#x2F;code&gt; function to specify whether a role can be revoked prematurely, enabling the standard to
support both use cases.&lt;&#x2F;p&gt;
&lt;p&gt;Regardless of the value of &lt;code&gt;revocable&lt;&#x2F;code&gt;, it&#x27;s recommended always to enable the &lt;code&gt;recipient&lt;&#x2F;code&gt; to revoke roles, allowing them
to eliminate undesirable assignments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;custom-data&quot;&gt;Custom Data&lt;&#x2F;h3&gt;
&lt;p&gt;DApps can customize roles using the &lt;code&gt;data&lt;&#x2F;code&gt; parameter of the &lt;code&gt;grantRole&lt;&#x2F;code&gt; function. &lt;code&gt;data&lt;&#x2F;code&gt; is implemented using the
generic type &lt;code&gt;bytes&lt;&#x2F;code&gt; to enable dApps to encode any role-specific information when granting a role. The custom
data is retrievable using the &lt;code&gt;roleData&lt;&#x2F;code&gt; function and is emitted with the &lt;code&gt;RoleGranted&lt;&#x2F;code&gt; event. With this approach,
developers can integrate this information into their applications, both on-chain and off-chain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;role-approval&quot;&gt;Role Approval&lt;&#x2F;h3&gt;
&lt;p&gt;Similar to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, this standard enable other accounts to manage roles on behalf of the NFT owner. This
functionality was introduced to allow third-parties to interact with ERC-7432 without requiring NFT ownership. Compliant
contracts MUST implement the functions &lt;code&gt;setRoleApprovalForAll&lt;&#x2F;code&gt; and &lt;code&gt;isRoleApprovedForAll&lt;&#x2F;code&gt; to deliver this feature.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;On all functions and events, the standard requires both the &lt;code&gt;tokenAddress&lt;&#x2F;code&gt; and &lt;code&gt;tokenId&lt;&#x2F;code&gt; to be provided. This
requirement enables dApps to use a standalone &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7432&#x2F;&quot;&gt;ERC-7432&lt;&#x2F;a&gt; contract as the authoritative source for the
roles of immutable NFTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7432&#x2F;.&#x2F;assets&#x2F;ERC7432.sol&quot;&gt;ERC-7432.sol&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Developers integrating the Non-Fungible Token Roles interface should consider the following on their implementations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure proper access controls are in place to prevent unauthorized role assignments or revocations.&lt;&#x2F;li&gt;
&lt;li&gt;Take into account potential attack vectors such as reentrancy and ensure appropriate safeguards are in place.&lt;&#x2F;li&gt;
&lt;li&gt;Approved accounts should be able to manage roles on behalf of another user. However, ensure that the NFT can
only be transferred to an escrow contract, and back to its original owner (not to the approved account).&lt;&#x2F;li&gt;
&lt;li&gt;Always check the expiration date before allowing users to access the utility of an NFT.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC&#x2F;EIP Repository split</title>
        <published>2023-07-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	<author>
		<name>Danno Ferrin</name><uri>https://github.com/shemnon</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7329/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/proposal-forking-ercs-from-eips-repository/12804" />
        

        <id>https://wg-eips.ritovision.com/7329/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:7329"
            label="EIP-7329" />
        

        
        

        
        <summary type="html">Split the ERC specifications out of the EIP repository into a new repository, so that only core protocol EIPs remain</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7329/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Describes the motivation and rational for splitting the EIP repositories into an
EIP repository, targeting core ethereum changes and an ERC repository, targeting
application layer specifications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Long ago when the EIPs repository was created, there was a vision of a single
home for all standards related to Ethereum. The community was small and most
people were interacting at every level of the ecosystem. It made sense to
combine application standards with core consensus changes.&lt;&#x2F;p&gt;
&lt;p&gt;Since then, the ecosystem has grown. Today, the chasm between application
development and core development is wide. Fewer people are involved across the
ecosystem (for better or worse); yet the repository remains unified.&lt;&#x2F;p&gt;
&lt;p&gt;For years, we&#x27;ve considered separating the repository. This would allow ERC and
EIP specifications to evolve more naturally due to the independence. But it&#x27;s
always difficult to reach critical threshold to make a change like this happen.
Each time we get lost in the details of the migration and the debate grinds
progress to a halt.&lt;&#x2F;p&gt;
&lt;p&gt;Now that the Consensus Layer is also utilizing the EIP process, the cracks are
becoming more visible. There are changes we could make to the process that might
benefit them more, but because we also need to ensure the quality of ERCs, we
are restricted.&lt;&#x2F;p&gt;
&lt;p&gt;There are also many more efforts to catalyze applications around the ERC
process. Attempts have been made to develop working groups and review groups for
certain ERC &quot;categories&quot; (a distinction that doesn&#x27;t even technically exist
because of the unified repo).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;This specification only details with the initial mechanism of the split. The
particulars of how each repository will govern itself is out of scope for this
EIP, as it is the motivating point of this EIP that the divergent needs of the
community will require highly divergent methods.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;All ERCs and Interface-category EIPs are removed from this repository and
migrated to a new repo. The history should be intact so that repo should be
forked of this one with the non-ERCs removed.&lt;&#x2F;li&gt;
&lt;li&gt;The new ERCs repository goes live and includes the changes from the script.&lt;&#x2F;li&gt;
&lt;li&gt;Setup ercs.ethereum.org subdomain and update the CI to point to the ERCs
repo.&lt;&#x2F;li&gt;
&lt;li&gt;Set up a redirect for ERCs on eips.ethereum.org to go to the new website.&lt;&#x2F;li&gt;
&lt;li&gt;Create a unified document for editors to assign EIP&#x2F;ERC numbers. EIPs and
ERCs will no longer be based on an initial PR number but on a number
incremented by the EIP editors of their respective repositories. EIPs will be
assigned even numbers and ERCs will be assigned odd numbers. The exact timing
of this migration is a policy decision of the editors.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The EIP repository will be associated with core protocol changes, specifically
the kind that would be discussed in one of the AllCoreDevs calls; whereas the
ERC repository will be affiliated with all remaining areas such as smart
contract application interfaces, wallet standards, DeFi protocol standards, and
all other such improvements that do not require core protocol changes.&lt;&#x2F;p&gt;
&lt;p&gt;This association is to persist across any other process changes the EIP editors
may introduce such as working groups, topic groups, expert groups, special
interest groups, splitting of the process, or other such changes. Any
sub-groupings that includes core protocol changes would be associated with the
EIP repository and other sub-groupings are associated with the ERC repository.
Any such process change are out of scope of this EIP and are independent of the
structural changes to the repositories specified in this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;There may be further structural changes to repository layouts to accommodate
more sub-groupings. Such proposals are out of scope of this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;There are two major communities served by the EIP process that are highly
divergent and very differentiated in their needs.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s consider the impact of specification ambiguity, the impacts are different
based on the community. The core protocol community has a low tolerance for
difference of implementation and a high penalty for specification ambiguity. An
improperly implemented part of a new spec could cause the ethereum mainnet to
split, possibly costing millions to billions of value lost to node operators as
well as community members using the services offered by the Ethereum protocols.
A poorly specified solidity interface, however, can be adapted and implemented
in multiple compatible ways across any smart choosing to implement it. A missing
RPC API (such as a configuration option specifying the number of decimals in the
chains native currency) can have limited to zero impact on the rest of the
community not choosing to use that wallet.&lt;&#x2F;p&gt;
&lt;p&gt;Timeframe for delivery of a feature is also similarly differentiated. A Core
protocol EIP adjusting the gas cost for transaction data needs to be rolled out
at a specific time uniformly across the network. Whereas a new RPC to support
new semantics to gas estimation would not need uniform rollout across the
Ethereum clients, and in fact would also need to be rolled out by service
provides that provide RPC services for Ethereum networks. Wallets can use early
support as a differentiating factor in their appeal to community members.&lt;&#x2F;p&gt;
&lt;p&gt;To address this divergence the AllCoreDevs call has adopted a lifecycle for EIPs
different from the Draft -&amp;gt; Review -&amp;gt; Last Call -&amp;gt; Final lifecycle of the EIP
repository. It would best be described as Draft -&amp;gt; Eligible for Inclusion -&amp;gt;
Considered for Inclusion -&amp;gt; Testnet -&amp;gt; Mainnet. The EIPs also get slotted for a
fork in the third step, a consideration that simply does not apply to a smart
contract or wallet standard.&lt;&#x2F;p&gt;
&lt;p&gt;Several alternatives have been proposed, but the actual implementation only
further underscores the specialization that each side of the split encounters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-working-groups&quot;&gt;Alternative: Working Groups&lt;&#x2F;h3&gt;
&lt;p&gt;One repeated concern of editors is that they often lack the technical experience
to adequately judge if an EIP is complete and sound. Considering that EIPs
covers wide variety of topics such as elliptic curve cryptography, VM
performance, DeFi market dynamics, compression protocols, NFT Royalties, and
consensus protocols it is impossible for a single editor to provide sensible
feedback on every one of those topics.&lt;&#x2F;p&gt;
&lt;p&gt;When examining how the core protocol and ERC communities would approach the
working group process, however, it underscores how different they would handle
it. For core protocol change the working group would be one of the two
AllCoreDevs meetings, either AllCoreDevs-Execution or AllCoreDevs-Consensus. And
sometimes both. There is no EIP that would be shipped in mainnet that would not
first be extensively considered by one of these two groups.&lt;&#x2F;p&gt;
&lt;p&gt;ERC proposals have no such standing groups. Wallet impacting changes may go
through the AllWalletDevs group, but it is entirely possible for a wallet or
group of wallets to collaborate on a protocol outside AllWalletDevs. Smart
contract APIs have no such standing meeting.&lt;&#x2F;p&gt;
&lt;p&gt;The Working Group model, however, would be a critical social signal for the ERC
community. It would signal a critical mass for a particular proposal issue if
enough experts could get together to agree to review a set of changes.&lt;&#x2F;p&gt;
&lt;p&gt;While working groups are excellent for the ERC community, it is overhead for the
core protocol community that would only add friction to an already established
process with know governance checkpoints.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-specialized-editors&quot;&gt;Alternative: Specialized Editors&lt;&#x2F;h3&gt;
&lt;p&gt;This alternative has already been implemented with the introduction of the
&lt;code&gt;eip-editors.yml&lt;&#x2F;code&gt; file. This allows for different groups of editors to review
different types of EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;There has been no measurable impact on the divergence of the community. Most
categories have a significant overlap with other categories.&lt;&#x2F;p&gt;
&lt;p&gt;This alternative does not address the governance and workflow issues that the
Core Protocol Developers would want to implement. All subgroups would still be
subject to the same workflow as other groups.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-pain-unrelated-to-process-divergences&quot;&gt;Alternative: Pain unrelated to process divergences&lt;&#x2F;h3&gt;
&lt;p&gt;This is a catch-all for a number of proposals, from allowing discord links in
discussion-to to allowing more freedom in external links.&lt;&#x2F;p&gt;
&lt;p&gt;While the theory that this may reduce the total amount of pain felt by users and
editors, bringing the pain level down to a more acceptable level, this does not
address the core divergence issue. Many of these pain relief proposals should
probably be done anyway, weather or not the EIP repository splits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-replace-eip-editors-with-ai-chatbots&quot;&gt;Alternative: Replace EIP Editors with AI Chatbots&lt;&#x2F;h3&gt;
&lt;p&gt;Nobody wins in this proposal. We would instead end up debating training sets,
competing implementations, and whether to use commercial providers. And
that&#x27;s if things go well.&lt;&#x2F;p&gt;
&lt;p&gt;AI chatbots, however, would not be able to compartmentalize the divergent needs
of the multiple groups if all adjudication were to be handled with one model or
one chat session. Higher quality output would be received if separate training
repositories were used for each major functional area.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternatives-are-not-mutually-exclusive&quot;&gt;Alternatives are not Mutually Exclusive&lt;&#x2F;h3&gt;
&lt;p&gt;It is critical to note that most of the discussed alternatives all have merits
and address important pain points. The adoption of a split should not be viewed
as a rejection of those alternatives. To quote a famous internet meme &quot;Why Not
Both?&quot;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;objection-this-splits-the-ethereum-community&quot;&gt;Objection: This splits the ethereum community&lt;&#x2F;h3&gt;
&lt;p&gt;One objection is that splitting the repository would result in the community no
longer being able to say &quot;we are all of us Ethereum Magicians.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;First it is important to note that such splits are already occurring. The
AllCoreDevs call has split into a Consensus and Execution layer call. ACD calls
no longer discuss client issues like wallet apis, the AllWalletDevs call has
adopted those issues and has grown into user experience issues. Cross chain
issues have been adopted by the Chain Agnostic Improvement Process (CAIP) group.&lt;&#x2F;p&gt;
&lt;p&gt;Rather than splitting this should be viewed as &quot;sharding&quot;, where a sub-community
of interest rallies around a shared sub issue, and by gathering are able to
increase the total scope of the community. CAIP is a perfect example where
operating separate from EIPs have allowed them to strengthen the ethereum
community.&lt;&#x2F;p&gt;
&lt;p&gt;Is a single cell organism weakened when it grows large and then splits into two?
Is an animal weakened when cells split and specialize into different tasks? It
is this very act of division and specialization that allows it to accomplish the
things that would be impossible as a single uniform cell.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;objection-this-should-be-an-eip-1-proposal&quot;&gt;Objection: This should be an  &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1&#x2F;&quot;&gt;EIP-1&lt;&#x2F;a&gt; proposal&lt;&#x2F;h3&gt;
&lt;p&gt;Since this is directly impacting the ERC process it should be documented
in  &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1&#x2F;&quot;&gt;EIP-1&lt;&#x2F;a&gt; first.&lt;&#x2F;p&gt;
&lt;p&gt;As the old programming adage goes: &quot;Refactor first before adding any new
features.&quot;  Adding new processes specific to the post-split governing docs would
only confuse the existing process, adding special cases for one class of EIPs
that don&#x27;t apply to another. It is precisely this kind of problem the proposed
split is aiming to change.&lt;&#x2F;p&gt;
&lt;p&gt;This is also valid grounds for a Meta category EIP, as how many and which
repository to put a proposal in is core to the &quot;procedures, guidelines, [and]
changes to the decision-making process&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Some process changes that can be expected in a Core Protocol EIP may include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Changing the work flow to add the Eligible for Inclusion&#x2F;Considered for
Inclusion stages to a pre-last-call EIP.&lt;&#x2F;li&gt;
&lt;li&gt;Adding test net and mainnet steps to the lifecycle&lt;&#x2F;li&gt;
&lt;li&gt;Adding a &quot;fork&quot; header to the RFCs section, for EIPs that are (or will be)
implemented in a specific fork&lt;&#x2F;li&gt;
&lt;li&gt;Changing the testing section to a header link to reference tests&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some process change ERC may want to adopt:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A strong working group model and adding an optional &quot;forming working group&quot;
step editors may require.&lt;&#x2F;li&gt;
&lt;li&gt;Add an &quot;outdated&quot; or &quot;replaced&quot; lifecycle step for EIPs that are abrogated by
future specs.&lt;&#x2F;li&gt;
&lt;li&gt;Deputize single-eip reviewers for specific EIPs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;objection-structural-changes-to-a-repository-and-process-changes-do-not-need-to-be-bundled&quot;&gt;Objection: Structural changes to a repository and process changes do not need to be bundled.&lt;&#x2F;h3&gt;
&lt;p&gt;It is possible to split the structure of the repositories separately from any
EIP process changes related to this. Bundling the changes is unnecessary and
such structure and process changes should be handled independently.&lt;&#x2F;p&gt;
&lt;p&gt;To accommodate this objection this EIP has been revised to only address
structural changes in the repository and can be adapted to any other,
independent, process changes and mapped onto those outcomes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;old-links&quot;&gt;Old Links&lt;&#x2F;h3&gt;
&lt;p&gt;Old ERC links pointing to the old url &lt;code&gt;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;&lt;&#x2F;code&gt; will continue
to work. Redirect instructions will be put into place to redirect to the new ERC
repos for their corresponding location.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;stray-proposals&quot;&gt;Stray Proposals&lt;&#x2F;h3&gt;
&lt;p&gt;ERC community members may continue to post new ERCs in the EIP proposal. Editors
will be able to redirect them to the new repository. ERCs that do not respond to
editor requests would not be merged anyway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal only addresses the EIP and ERC proposal process and is not
expected to expose any new attack surfaces by virtue of its adoption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Increase the MAX_EFFECTIVE_BALANCE</title>
        <published>2023-06-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>mike</name><uri>https://github.com/michaelneuder</uri>
	</author>
	
	<author>
		<name>Francesco</name><uri>https://github.com/fradamt</uri>
	</author>
	
	<author>
		<name>dapplion</name><uri>https://github.com/dapplion</uri>
	</author>
	
	<author>
		<name>Mikhail</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	<author>
		<name>Aditya</name><uri>https://github.com/adiasg</uri>
	</author>
	
	<author>
		<name>Justin</name><uri>https://github.com/justindrake</uri>
	</author>
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	<author>
		<name>Felix Lange</name><uri>https://github.com/fjl</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7251/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7251-increase-the-max-effective-balance/15982" />
        

        <id>https://wg-eips.ritovision.com/7251/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7251"
            label="EIP-7251" />
        

        
        

        
        <summary type="html">Allow validators to have larger effective balances, while maintaining the 32 ETH lower bound.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7251/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Increases the constant &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;, while keeping the minimum staking balance &lt;code&gt;32 ETH&lt;&#x2F;code&gt;. This permits large node operators to consolidate into fewer validators while also allowing solo-stakers to earn compounding rewards and stake in more flexible increments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As of October 3, 2023, there are currently over 830,000 validators participating in the consensus layer. The size of this set continues to grow due, in part, to the &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;, which limits the stake of a single validator to &lt;code&gt;32 ETH&lt;&#x2F;code&gt;. This leads to large amounts of &quot;redundant validators&quot;, which are controlled by a single entity, possibly running on the same beacon node, but with distinct BLS signing keys. The limit on the &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt; is technical debt from the original sharding design, in which subcommittees (not the attesting committee but the committee calculated in &lt;code&gt;is_aggregator&lt;&#x2F;code&gt;) needed to be majority honest. As a result, keeping the weights of subcommittee members approximately equal reduced the risk of a single large validator containing too much influence. Under the current design, these subcommittees are only used for attestation aggregation, and thus only have a &lt;code&gt;1&#x2F;N&lt;&#x2F;code&gt; honesty assumption.&lt;&#x2F;p&gt;
&lt;p&gt;With the security model of the protocol no longer dependent on a low value for &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;, we propose raising this value while keeping the minimum validator threshold of &lt;code&gt;32 ETH&lt;&#x2F;code&gt;. This increase aims to reduce the validator set size, thereby reducing the number of P2P messages over the network, the number of BLS signatures that need to be aggregated each epoch, and the &lt;code&gt;BeaconState&lt;&#x2F;code&gt; memory footprint. This change adds value for both small and large validators. Large validators can consolidate to run fewer validators and thus fewer beacon nodes. Small validators now benefit from compounding rewards and the ability to stake in more flexible increments (e.g., the ability to stake &lt;code&gt;40 ETH&lt;&#x2F;code&gt; instead of needing to accumulate &lt;code&gt;64 ETH&lt;&#x2F;code&gt; to run two validators today).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;execution-layer&quot;&gt;Execution layer&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_TYPE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x02&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; type prefix for consolidation request&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0000BBdDc7CE488642fb579F8B00f3a590007251&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Where to call and store relevant details about consolidation request mechanism&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address used to invoke system operation on contract&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXCESS_CONSOLIDATION_REQUESTS_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Pointer to the head of the consolidation request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Pointer to the tail of the consolidation request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;The start memory slot of the in-state consolidation request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Maximum number of consolidation requests that can be dequeued into a block&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_CONSOLIDATION_REQUEST_FEE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CONSOLIDATION_REQUEST_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;17&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXCESS_INHIBITOR&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**256-1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Excess value used to compute the fee before the first system call&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;COMPOUNDING_WITHDRAWAL_PREFIX&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes1(&#x27;0x02&#x27;)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Gwei(2**5 * 10**9)&lt;&#x2F;code&gt;  (32 ETH)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_EFFECTIVE_BALANCE_ELECTRA&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Gwei(2**11 * 10**9)&lt;&#x2F;code&gt; (2048 ETH)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;execution-layer-1&quot;&gt;Execution layer&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;consolidation-request&quot;&gt;Consolidation request&lt;&#x2F;h4&gt;
&lt;p&gt;The new consolidation request is an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; request with type &lt;code&gt;0x02&lt;&#x2F;code&gt; consisting of the following fields:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;source_address&lt;&#x2F;code&gt;: &lt;code&gt;Bytes20&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;source_pubkey&lt;&#x2F;code&gt;: &lt;code&gt;Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;target_pubkey&lt;&#x2F;code&gt;: &lt;code&gt;Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; encoding of a consolidation request is as follows. Note we simply return the encoded request value as returned by the contract.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dequeue_consolidation_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;consolidation-request-contract&quot;&gt;Consolidation request contract&lt;&#x2F;h4&gt;
&lt;p&gt;The contract has three different code paths, which can be summarized at a high level as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add consolidation request - requires a &lt;code&gt;96&lt;&#x2F;code&gt; byte input, concatenated public keys of the source and the target validators.&lt;&#x2F;li&gt;
&lt;li&gt;Fee getter - if the input length is zero, return the current fee required to add a consolidation request.&lt;&#x2F;li&gt;
&lt;li&gt;System process - if called by system address, pop off the consolidation requests for the current block from the queue.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h5 id=&quot;add-consolidation-request&quot;&gt;Add Consolidation Request&lt;&#x2F;h5&gt;
&lt;p&gt;If call data input to the contract is exactly &lt;code&gt;96&lt;&#x2F;code&gt; bytes, perform the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure enough ETH was sent to cover the current consolidation request fee (&lt;code&gt;msg.value &amp;gt;= get_fee()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Increase consolidation request count by &lt;code&gt;1&lt;&#x2F;code&gt; for the current block (&lt;code&gt;increment_count()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Insert a consolidation request into the queue for the source address and pubkeys of the source and the target (&lt;code&gt;insert_consolidation_request_into_queue()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Specifically, the functionality is defined in pseudocode as the function &lt;code&gt;add_consolidation_request()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add_consolidation_request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;Bytes48&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; source_pubkey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; Bytes48&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; target_pubkey&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Add consolidation request adds new request to the consolidation request queue, so long as a sufficient fee is provided.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify sufficient fee was provided.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_fee&lt;&#x2F;span&gt;&lt;span&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&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; fee&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Insufficient value for fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increment consolidation request count.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Insert into queue.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; source_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; source_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt; target_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; target_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h6 id=&quot;fee-calculation&quot;&gt;Fee calculation&lt;&#x2F;h6&gt;
&lt;p&gt;The following pseudocode can compute the cost of an individual consolidation request, given a certain number of excess consolidation requests.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_fee&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_CONSOLIDATION_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_INHIBITOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Inhibitor still active&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        MIN_CONSOLIDATION_REQUEST_FEE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        excess&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        CONSOLIDATION_REQUEST_FEE_UPDATE_FRACTION&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; denominator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;denominator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;fee-getter&quot;&gt;Fee Getter&lt;&#x2F;h5&gt;
&lt;p&gt;When the input to the contract is length zero, interpret this as a get request for the current fee, i.e. the contract returns the result of &lt;code&gt;get_fee()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;system-call&quot;&gt;System Call&lt;&#x2F;h5&gt;
&lt;p&gt;At the end of processing any execution block where this EIP is active (i.e. after processing all transactions and after performing the block body consolidation requests validations), call the contract at &lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; as &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; with no calldata. The invocation triggers the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The contract&#x27;s queue is updated based on consolidation requests dequeued and the consolidation requests queue head&#x2F;tail are reset if the queue has been cleared (&lt;code&gt;dequeue_consolidation_requests()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;The contract&#x27;s excess consolidation requests are updated based on usage in the current block (&lt;code&gt;update_excess_consolidation_requests()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;The contract&#x27;s consolidation requests count is reset to &lt;code&gt;0&lt;&#x2F;code&gt; (&lt;code&gt;reset_consolidation_requests_count()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each consolidation request must appear in the EIP-7685 requests list in the exact order returned by &lt;code&gt;dequeue_consolidation_requests()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the system call and the processing of that block must conform to the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The call has a dedicated gas limit of &lt;code&gt;30_000_000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Gas consumed by this call does not count against the block’s overall gas usage.&lt;&#x2F;li&gt;
&lt;li&gt;Both the gas limit assigned to the call and the gas consumed are excluded from any checks against the block’s gas limit.&lt;&#x2F;li&gt;
&lt;li&gt;The call does not follow &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt; fee burn semantics — no value should be transferred as part of this call.&lt;&#x2F;li&gt;
&lt;li&gt;If there is no code at &lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;, the corresponding block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be marked invalid.&lt;&#x2F;li&gt;
&lt;li&gt;If the call to the contract fails or returns an error, the block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be invalidated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The functionality triggered by the system call is defined in pseudocode as the function &lt;code&gt;process_consolidation_requests()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;##################&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Public function #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; process_consolidation_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    reqs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dequeue_consolidation_requests&lt;&#x2F;span&gt;&lt;span&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&gt;    update_excess_consolidation_requests&lt;&#x2F;span&gt;&lt;span&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&gt;    reset_consolidation_requests_count&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ssz&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;serialize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;reqs&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;##########&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Helpers #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ConsolidationRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;object&lt;&#x2F;span&gt;&lt;span&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&gt;    source_address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    source_pubkey&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    target_pubkey&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes48&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; dequeue_consolidation_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    num_in_queue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; queue_head_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    num_dequeued&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;num_in_queue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;span&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&gt;    reqs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;num_dequeued&lt;&#x2F;span&gt;&lt;span&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&gt;        queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        source_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&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&gt;        source_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        req&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ConsolidationRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;            source_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Bytes20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;source_address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;            source_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Bytes48&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;source_pubkey&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;            target_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Bytes48&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;target_pubkey&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        reqs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;req&lt;&#x2F;span&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&gt;    new_queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; num_dequeued&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; new_queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Queue is empty, reset queue pointers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&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&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_queue_head_index&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; reqs&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; update_excess_consolidation_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_CONSOLIDATION_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if excess needs to be reset to 0 for first iteration after activation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_INHIBITOR&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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;    count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&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&gt;    new_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        new_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_CONSOLIDATION_REQUESTS_PER_BLOCK&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;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_CONSOLIDATION_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_excess&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; reset_consolidation_requests_count&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;bytecode&quot;&gt;Bytecode&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push20 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xd3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push32 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x019a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iszero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x68&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;div&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;div&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x88&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x019a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;callvalue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x019a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;callvalue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x019a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatacopy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xe7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0129&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xe9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x013b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0146&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push32 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iszero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0173&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0188&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x018e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;sub&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;deployment&quot;&gt;Deployment&lt;&#x2F;h5&gt;
&lt;p&gt;The consolidation requests contract is deployed like any other smart contract. A special synthetic address is generated by working backwards from the desired deployment transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3d090&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe8d4a51000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxPriorityFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f5561019e80602d5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x539&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xc0730f92dc275b663d377a7cbb141b6600052&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x379269d571beff3ed1d8eba3abb24076a7267b0eaf0cc66d728fb0544f5a690d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sender: 0x13d1913d623E6a9D8811736359E50fD31Fe54fCA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Address: 0x0000BBdDc7CE488642fb579F8B00f3a590007251&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;consensus-layer-1&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;p&gt;The defining features of this EIP are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Increasing the &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;, while creating a &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The core feature of allowing variable size validators.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Allowing for multiple validator indices to be combined through the protocol.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; A mechanism by which large node operators can combine validators without cycling through the exit and activation queues.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Adding execution layer partial withdrawals (part of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;&quot;&gt;EIP-7002&lt;&#x2F;a&gt;).&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; Allowing Execution Layer messages to trigger partial withdrawals in addition to full exits (e.g., a &lt;code&gt;100 ETH&lt;&#x2F;code&gt; validator can remove up to &lt;code&gt;68 ETH&lt;&#x2F;code&gt; without exiting the validator).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Making the initial slashing penalty negligible.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; This reduces the risk of consolidation for large validators.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7251&#x2F;#rationale&quot;&gt;Rationale&lt;&#x2F;a&gt; section contains an explanation for each of these proposed core features. A sketch of the resulting changes to the consensus layer is included below.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;COMPOUNDING_WITHDRAWAL_PREFIX&lt;&#x2F;code&gt; and &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt; constants, while introducing the updated value of &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt; (&lt;code&gt;MAX_EFFECTIVE_BALANCE_ELECTRA&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Create the &lt;code&gt;PendingDeposit&lt;&#x2F;code&gt; container, which is used to track incoming deposits in the weight-based rate limiting mechanism.&lt;&#x2F;li&gt;
&lt;li&gt;Update the &lt;code&gt;BeaconState&lt;&#x2F;code&gt; with deposit and partial withdrawal queues, fields needed for deposit, and exit queue weight-based rate limiting.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;is_eligible_for_activation_queue&lt;&#x2F;code&gt; to check against &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt; rather than &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;get_validator_churn_limit&lt;&#x2F;code&gt; to depend on the validator weight rather than the validator count.&lt;&#x2F;li&gt;
&lt;li&gt;Create a helper &lt;code&gt;compute_exit_epoch_and_update_churn&lt;&#x2F;code&gt; to calculate the exit epoch based on the current pending withdrawals.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;initiate_validator_exit&lt;&#x2F;code&gt; to rate limit the exit queue by balance rather than the number of validators.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;initialize_beacon_state_from_eth1&lt;&#x2F;code&gt; to use &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;process_registry_updates&lt;&#x2F;code&gt; to activate all eligible validators.&lt;&#x2F;li&gt;
&lt;li&gt;Add a per-epoch helper, &lt;code&gt;process_pending_deposits&lt;&#x2F;code&gt;, to consume some of the pending deposits.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;get_validator_from_deposit&lt;&#x2F;code&gt; to initialize the effective balance to zero (it&#x27;s updated by the pending deposit flow).&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;process_deposit&lt;&#x2F;code&gt; to store incoming deposits in &lt;code&gt;state.pending_deposits&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;compute_weak_subjectivity_period&lt;&#x2F;code&gt; to use the new churn limit function.&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;has_compounding_withdrawal_credential&lt;&#x2F;code&gt; to check for the &lt;code&gt;0x02&lt;&#x2F;code&gt; credential.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;is_fully_withdrawable_validator&lt;&#x2F;code&gt; to check for compounding credentials.&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;get_validator_excess_balance&lt;&#x2F;code&gt; to calculate the excess balance of validators.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;is_partially_withdrawable_validator&lt;&#x2F;code&gt; to check for excess balance.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;code&gt;get_expected_withdrawals&lt;&#x2F;code&gt; to use excess balance and process pending partial withdrawals.&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;process_consolidation&lt;&#x2F;code&gt; to initiate in-protocol validator consolidation and switch a validator to compounding withdrawal credentials.&lt;&#x2F;li&gt;
&lt;li&gt;Limits the usage of exit churn to 256 ETH (equivalent to 8 validators with 32 ETH effective balance), and defers the surplus of the churn to process consolidations.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Full consensus layer specification can be found in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;834e40604ae4411e565bd6540da50b008b2496dc&#x2F;specs&#x2F;electra&#x2F;beacon-chain.md&quot;&gt;&lt;code&gt;.&#x2F;electra&#x2F;beacon-chain.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP aims to reduce the total number of validators without changing anything about the economic security of the protocol. It provides a mechanism by which large node operators who control significant amounts of stake can consolidate into fewer validators. We analyze the reasoning behind each of the core features.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;increasing-the-max-effective-balance-while-creating-a-min-activation-balance&quot;&gt;Increasing the &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;, while creating a &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;While increasing the &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt; to allow larger-stake validators, it is important to keep the lower bound of &lt;code&gt;32 ETH&lt;&#x2F;code&gt; (by introducing a new constant – &lt;code&gt;MIN_ACTIVATION_BALANCE&lt;&#x2F;code&gt;) to encourage solo-staking.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;allowing-for-multiple-validator-indices-to-be-combined-through-the-protocol&quot;&gt;Allowing for multiple validator indices to be combined through the protocol&lt;&#x2F;h3&gt;
&lt;p&gt;For large staking pools that already control thousands of validators, exiting and re-entering would be extremely slow and costly. The adoption of the EIP will be much higher by allowing in-protocol consolidation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adding-execution-layer-partial-withdrawals-part-of-eip-7002&quot;&gt;Adding execution layer partial withdrawals (part of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;&quot;&gt;EIP-7002&lt;&#x2F;a&gt;)&lt;&#x2F;h3&gt;
&lt;p&gt;For validators that choose to raise their effective balance ceiling, allowing for custom partial withdrawals triggered from the execution layer increases the flexibility of the staking configurations. Validators can choose when and how much they withdraw but will have to pay gas for the EL transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;making-the-initial-slashing-penalty-negligible&quot;&gt;Making the initial slashing penalty negligible&lt;&#x2F;h3&gt;
&lt;p&gt;To encourage consolidation, we could modify the slashing penalties. The biggest hit comes from the initial penalty of &lt;code&gt;1&#x2F;32&lt;&#x2F;code&gt; of the validator&#x27;s effective balance. Since this scales linearly on the effective balance, the higher-stake validators directly incur higher risk. By changing the scaling properties, we could make consolidation more attractive.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consolidation-contract-parameter-values&quot;&gt;Consolidation contract parameter values&lt;&#x2F;h3&gt;
&lt;p&gt;The consolidation smart contract uses a fee mechanism to rate limit the number of requests per block. Details of the fee mechanism are available in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;#fee-update-rule&quot;&gt;EIP-7002&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;TARGET_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; is chosen to be &lt;code&gt;1&lt;&#x2F;code&gt; to rate limit consolidation requests as much as possible.
&lt;code&gt;MAX_CONSOLIDATION_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; is chosen to be &lt;code&gt;2&lt;&#x2F;code&gt; to allow for switching a validator to compounding credentials and requesting a consolidation in the same block.&lt;&#x2F;p&gt;
&lt;p&gt;One consolidation per block is still higher than the size of consolidation churn which can lead to unbounded growth of the consolidation queue.
Thus, there is a hard limit on the consolidation queue size equal to 262,144 requests which is &lt;code&gt;4 MB&lt;&#x2F;code&gt; of data in the beacon state.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backward incompatible changes to the block validation rule set and must be accompanied by a hard fork. These changes do not break anything related to current user activity and experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This change modifies committees and churn, but doesn&#x27;t significantly impact the security properties.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security-of-attestation-committees&quot;&gt;Security of attestation committees&lt;&#x2F;h3&gt;
&lt;p&gt;Given full consolidation as the worst case, the probability of an adversarial takeover of a committee remains low. Even in a high consolidation scenario, the required share of honest validators remains well below the 2&#x2F;3 supermajority needed for finality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aggregator-selection&quot;&gt;Aggregator selection&lt;&#x2F;h3&gt;
&lt;p&gt;In the original sharding roadmap, subcommittees were required to be secure with extremely high probability. Now with the sole responsibility of attestation aggregation, we only require each committee to have at least one honest aggregator. Currently, aggregators are selected through a VRF lottery, targeting several validator units that can be biased by non-consolidated attackers. This proposal changes the VRF lottery to consider weight, so the probability of having at least one honest aggregator is not worse.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proposer-selection-probability&quot;&gt;Proposer selection probability&lt;&#x2F;h3&gt;
&lt;p&gt;Proposer selection is already weighted by the ratio of their effective balance to &lt;code&gt;MAX_EFFECTIVE_BALANCE&lt;&#x2F;code&gt;. Due to the lower probabilities, this change will slightly increase the time it takes to calculate the next proposer index.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sync-committee-selection-probability&quot;&gt;Sync committee selection probability&lt;&#x2F;h3&gt;
&lt;p&gt;Sync committee selection is also already weighted by effective balance, so this proposal does not require modifications to the sync protocol. Light clients can still check that a super-majority of participants have signed an update irrespective of their weights since we maintain a weight-based selection probability.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;churn-invariants&quot;&gt;Churn invariants&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal maintains the activation and exit churn invariants limiting active weight instead of validator count. Balance top-ups are now handled explicitly, being subject to the same activation queue as full deposits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fee-overpayment&quot;&gt;Fee Overpayment&lt;&#x2F;h3&gt;
&lt;p&gt;Calls to the system contract require a fee payment defined by the current contract state. Overpaid fees are not returned to the caller. It is not generally possible to compute the exact required fee amount ahead of time. When adding a consolidation request from a contract, the contract can perform a read operation to check for the current fee and then pay exactly the required amount. Here is an example in Solidity:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function addConsolidation(bytes memory srcPubkey, bytes memory targetPubkey, uint64 requestFeeLimit) private {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(srcPubkey.length == 48);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(targetPubkey.length == 48);&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; Read current fee from the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (bool readOK, bytes memory feeData) = ConsolidationsContract.staticcall(&amp;#39;&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (!readOK) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;reading fee failed&amp;#39;);&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;    uint256 fee = uint256(bytes32(feeData));&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; Check the fee is not too high.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (fee &amp;gt; requestFeeLimit) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;fee is too high&amp;#39;);&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&gt;    &#x2F;&#x2F; Add the request.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes memory callData = bytes.concat(srcPubkey, targetPubkey);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (bool writeOK,) = ConsolidationsContract.call{value: fee}(callData);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (!writeOK) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;adding request failed&amp;#39;);&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;Note: the system contract uses the EVM &lt;code&gt;CALLER&lt;&#x2F;code&gt; operation (Solidity: &lt;code&gt;msg.sender&lt;&#x2F;code&gt;) to get the address used in the consolidation request, i.e. the address that calls the system contract must match the 0x01 withdrawal credential recorded in the beacon state.&lt;&#x2F;p&gt;
&lt;p&gt;Note: the above code reverts if the fee is too high, the fee can change significantly between the creation of a consolidation request transaction and its inclusion into a block, thus, this check is very important to avoid overpayments.&lt;&#x2F;p&gt;
&lt;p&gt;Using an EOA to request consolidations will always result in overpayment of fees. There is no way for an EOA to use a wrapper contract to request a consolidation. And even if a way existed, the gas cost of returning the overage would likely be higher than the overage itself. If requesting consolidations from an EOA to the system contract is desired, we recommend that users perform transaction simulations to estimate a reasonable fee amount to send.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consolidation-queue-hard-limit&quot;&gt;Consolidation queue hard limit&lt;&#x2F;h3&gt;
&lt;p&gt;Consolidations exceeding the hard limit of the consolidation queue (262,144 requests) will be discarded by the consensus layer and will need to be re-submitted,
note that the fee is not refunded in this case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-call-failure&quot;&gt;System Call failure&lt;&#x2F;h3&gt;
&lt;p&gt;Although the likelihood of a failed system call to &lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; is extremely low, the behavior in such cases is well-defined: the block is marked as invalid. This consideration directly follows from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;#system-call-failure&quot;&gt;EIP-7002&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;empty-code-failure&quot;&gt;Empty Code failure&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP should not have been activated if there is no code present at &lt;code&gt;CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; (i.e., if the chain is not &quot;ready&quot;). This is also similar to the consideration in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;#empty-code-failure&quot;&gt;EIP-7002&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Identity-aggregated NFT</title>
        <published>2023-06-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Chloe Gu</name><email>chloe@carv.io</email>
	</author>
	
	<author>
		<name>Navid X.</name><uri>https://github.com/xuxinlai2002</uri>
	</author>
	
	<author>
		<name>Victor Yu</name><email>victor@carv.io</email>
	</author>
	
	<author>
		<name>Archer H.</name>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7231/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc7231-identity-aggregated-nft/15062" />
        

        <id>https://wg-eips.ritovision.com/7231/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7231"
            label="ERC-7231" />
        

        
        

        
        <summary type="html">The aggregation of web2 &amp; web3 identities to NFTs, authorized by individuals, gives attributes of ownerships, relationships, experiences.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7231/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; by binding individuals&#x27; Web2 and Web3 identities to non-fungible tokens (NFTs) and soulbound tokens (SBTs). By binding multiple identities, aggregated and composible identity infomation can be verified, resulting in more beneficial onchain scenarios for individuals, such as self-authentication, social overlapping, commercial value generation from user targetting, etc. By adding a custom schema in the metadata, and updating and verifying the schema hash in the contract, the binding of NFT and identity information is completed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;One of the most interesting aspects of Web3 is the ability to bring an individual&#x27;s own identity to different applications. Even more powerful is the fact that individuals truly own their accounts without relying on centralized gatekeepers, disclosing to different apps components necessary for authentication and approved by individuals.
Exisiting solutions such as ENS, although open, decentralized, and more convenient for Ethereum-based applications, suffer from a lack of data standardization and authentication of identity due to inherent anominity. Other solutions such as SBTs rely on centralized attestors, can not prevent data tampering, and do not inscribe data into the ledger itself in a privacy enabling way.&lt;br &#x2F;&gt;
The proposed pushes the boundaries of solving identity problems with Identity Aggregated NFT, i.e., the individual-authenticated aggregation of web2 and web3 identities to NFTs (SBTs included).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;every-compliant-contract-must-implement-the-interface&quot;&gt;Every compliant contract must implement the Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7231&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; emit the use binding information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nft id &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; identitiesRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; new identity root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SetIdentitiesRoot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identitiesRoot&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the user ID binding information of NFT with identitiesRoot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nft id &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; identitiesRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; multi UserID Root data hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST allow external calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setIdentitiesRoot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identitiesRoot&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get the multi-userID root by  NFTID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nft id &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST return the bytes32 multiUserIDsRoot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST NOT modify the state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST allow external calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getIdentitiesRoot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; verify the userIDs binding &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nft id &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userIDs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; userIDs for check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; identitiesRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; msg hash to verify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ECDSA signature &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST If the verification is passed, return true, otherwise return false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST NOT modify the state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * MUST allow external calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verifyIdentitiesBinding&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nftOwnerAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userIDs&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identitiesRoot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the “Metadata JSON Schema” referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;MultiIdentities&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;userID&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;User ID of Web2 and web3(DID)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;verifierUri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Verifier Uri of the userID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;memo&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Memo of the userID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;properties of the user ID information&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following problems that are solved by this standard:
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7231&#x2F;.&#x2F;assets&#x2F;img&#x2F;Identity-aggregated-NFT-flow.png&quot; alt=&quot;EIP Flow Diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Resolve the issue of multiple ID bindings for web2 and web3.
By incorporating the MultiIdentities schema into the metadata file, an authorized bond is established between user identity information and NFTs. This schema encompasses a userID field that can be sourced from a variety of web2 platforms or a decentralized identity (DID) created on blockchain. By binding the NFT ID with the UserIDInfo array, it becomes possible to aggregate multiple identities seamlessly.&lt;&#x2F;li&gt;
&lt;li&gt;Users have full ownership and control of their data
Once the user has set the metadata, they can utilize the setIdentitiesRoot function to establish a secure binding between hashed userIDs objects and NFT ID. As only the user holds the authority to carry out this binding, it can be assured that the data belongs solely to the user.&lt;&#x2F;li&gt;
&lt;li&gt;Verify the binding relationship between data on-chain and off-chain data through signature based on &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;
Through the signature method based on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; protocol, the verifyIdentiesBinding function of this EIP realizes the binding of the userID and NFT owner address between on-chain and off-chain.
&lt;ol&gt;
&lt;li&gt;NFT ownership validation&lt;&#x2F;li&gt;
&lt;li&gt;UserID format validation&lt;&#x2F;li&gt;
&lt;li&gt;IdentitiesRoot Consistency verification&lt;&#x2F;li&gt;
&lt;li&gt;Signature validation from nft owner&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As for how to verify the authenticity of the individuals&#x27; identities, wallets, accounts, there are various methods, such as zk-based DID authentication onchain, and offchain authentication algorithms, such as auth2, openID2, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the specifications section, this standard can be fully &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; compatible by adding an extension function set.
In addition, new functions introduced in this standard have many similarities with the existing functions in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. This allows developers to easily adopt the standard quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7231&#x2F;.&#x2F;assets&#x2F;test&#x2F;erc7231.ts&quot;&gt;&lt;code&gt;erc7231.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-7231&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;ERC7231.sol&lt;&#x2F;code&gt; Implementation: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7231&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC7231.sol&quot;&gt;&lt;code&gt;ERC7231.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standard can comprehensively empower individuals to have ownership and control of their identities, wallets, and relevant data by themselves adding or removing the NFTs and identity bound information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Purpose bound money</title>
        <published>2023-06-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Orchid-Dev</name><uri>https://github.com/proj-orchid-straitsx</uri>
	</author>
	
	<author>
		<name>Victor Liew</name><uri>https://github.com/alcedo</uri>
	</author>
	
	<author>
		<name>Wong Tse Jian</name><uri>https://github.com/wongtsejian</uri>
	</author>
	
	<author>
		<name>Jacob Shan</name><uri>https://github.com/Jacobshan429</uri>
	</author>
	
	<author>
		<name>Chin Sin Ong</name><uri>https://github.com/chinsinong</uri>
	</author>
	
	<author>
		<name>Praveen Kumar</name><uri>https://github.com/veenkumarr</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7291/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7291-purpose-bound-money/14973" />
        

        <id>https://wg-eips.ritovision.com/7291/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7291"
            label="ERC-7291" />
        

        
        

        
        <summary type="html">An extension to ERC-1155 implementing a hybrid form of programmable payment and money.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7291/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A Purpose Bound Money (PBM) token is a wrapper around an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; token that can be used for a limited activity. This proposal outlines a smart contract interface that builds upon the ERC-1155 standard to implement the purpose bound money (PBM) concept:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A PBM consists of a PBM wrapper and the digital money token it wraps. A digital money token (e.g., stablecoins, central bank digital currencies, tokenized bank deposits, and similar instruments) serves as a store of value (abbreviated as &quot;sov&quot;). Thus, a digital money token (also referred to as &quot;sovToken&quot;) &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be:
&lt;ul&gt;
&lt;li&gt;a good store of value;&lt;&#x2F;li&gt;
&lt;li&gt;a suitable unit of account; and&lt;&#x2F;li&gt;
&lt;li&gt;a medium of exchange.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;PBMs are bearer instruments, with self-contained programming logic, and can be transferred between two parties without involving intermediaries. It combines the concept of:
&lt;ul&gt;
&lt;li&gt;programmable payment - automatic execution of payments once a pre-defined set of conditions are met; and&lt;&#x2F;li&gt;
&lt;li&gt;programmable money - the possibility of embedding rules within the medium of exchange itself that define or constrain its usage.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Once the conditions are met, sovToken is released, and it becomes unbounded once again. A PBM can be thought of as a digital cash voucher, because it places constraints on how a payer can use the PBM but does not impose any constraints on the merchant&#x2F;redeemer because the PBM unwraps and releases the underlying digital money upon payment to the merchant&#x2F;redeemer. This is akin to a physical cash voucher: the payer is restricted to purchases from the merchants specified by the issuer but the merchants accepting the vouchers can exchange the physical vouchers with the issuer for fiat money.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this EIP, we propose a modular structure consisting of a sovToken compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; as the digital money, an ERC-1155 compatible smart contract as the PBM wrapper, a compliance guard smart contract as a component of the PBM Wrapper logic, and a PBM token manager smart contract to manage token registration and retrieval.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Purpose Bound Money (PBM) enables digital currencies to carry conditions on how they can be spent, making them especially useful in real-world scenarios such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Government vouchers&lt;&#x2F;strong&gt; (e.g. CDC vouchers in Singapore), where funds should only be redeemable at approved heartland merchants;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Conditional disbursements&lt;&#x2F;strong&gt;, such as SkillsFuture learning accounts, where funds are released only after course participation is verified;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Escrow-style payments&lt;&#x2F;strong&gt;, like homebuyer milestones, where payouts to developers are tied to the completion of specific construction stages;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal intends to forestall technology fragmentation and consequently a lack of interoperability. By making the PBM specification open, it gives new participants easy and free access to the pre-existing market standards, enabling interoperability across different platforms, wallets, payment systems and rails. This would lower cost of entry for new participants, foster a vibrant payment landscape and prevent the development of walled gardens and monopolies, ultimately leading to more efficient, affordable services and better user experiences.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sovToken&lt;&#x2F;strong&gt; - an ERC-20 or ERC-20 compatible digital currency (e.g. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1363&#x2F;&quot;&gt;ERC-1363&lt;&#x2F;a&gt;) serving as the store of value token (i.e. collateral backing the PBM Token).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PBM Wrapper&lt;&#x2F;strong&gt; - an ERC-1155 compliant smart contract, which wraps the sovToken by specifying one or more conditions that have to be met (referred to as PBM business logic in subsequent section of this proposal). The PBM wrapper can be designed to be modular in nature, with core, plug-ins and hooks components (see section on PBM Architecture for elaboration). The PBM wrapper smart contract, together with adopted hooks smart contracts verifies that condition(s) has&#x2F;have been met before unwrapping the underlying sovToken.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PBM Token&lt;&#x2F;strong&gt; - the sovToken and its PBM wrapper are collectively referred to as a PBM Token. PBM Tokens are represented as ERC-1155 tokens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PBM Creator&lt;&#x2F;strong&gt; defines the conditions of the PBM Wrapper to create PBM Tokens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Merchant &#x2F; Redeemer&lt;&#x2F;strong&gt; - In the context of this proposal, a Merchant or a Redeemer is broadly defined as the ultimate recipient, or endpoint, for PBM tokens, to which these tokens are intrinsically directed or purpose-bound to. The identity of merchant&#x2F;redeemer will be one of the validations performed by the compliance guard, which may be implemented as part of the PBM Wrapper smart contract or as a standalone compliance guard contract registered as a PBM hook.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PBM &lt;strong&gt;SHALL&lt;&#x2F;strong&gt; adhere to the definition of &quot;wrap&quot; or &quot;wrapping&quot; to mean binding a token in accordance with PBM business logic throughout its lifecycle.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;PBM &lt;strong&gt;SHALL&lt;&#x2F;strong&gt; adhere to the definition of &quot;unwrap&quot; or &quot;unwrapping&quot; to mean the release of a token in accordance with the PBM business logic during its lifecycle stage.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A valid PBM Token &lt;strong&gt;MUST&lt;&#x2F;strong&gt; consist of an underlying sovToken and a PBM Wrapper.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The sovToken can be wrapped either upon the creation of the PBM Token or at a later date.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A sovToken can be implemented as any widely accepted ERC-20 compatible token, such as ERC-20, ERC-777, or ERC-1363.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;PBM Wrapper &lt;strong&gt;MUST&lt;&#x2F;strong&gt; provide a mechanism for all transacting parties to verify that all necessary condition(s) have been met before allowing the PBM Token to be unwrapped. Refer to Auditability section for elaborations. The necessary conditions can be implemented within the PBM wrapper, or in a separate PBM hook(s) smart contract(s).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;PBM Wrapper &lt;strong&gt;MUST&lt;&#x2F;strong&gt; ensure the destination address for unwrapped sovToken is in a whitelist of Merchant&#x2F;Redeemer addresses and not in a blacklist of banned addresses prior to unwrapping the underlying sovToken.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The PBM Token &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be burnt upon being fully unwrapped and used.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A PBM Token &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; have an expiry time that is decided by the PBM Creator.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For cases where an expiry time is not needed, the expiry time &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be set to infinity (typically represented as the maximum value of uint256 or type(uint256).max).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This proposal defines a base specification of what a PBM should entail. Extensions to this base specification can be implemented as separate specifications.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;pbm-architecture&quot;&gt;PBM Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;In this EIP, we propose a modular PBM architecture that has three distinct components (the core, the plugins and the hooks):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;core components&lt;&#x2F;strong&gt; contains basic functionalities and validation checks that all PBMs should have. Core components includes sovToken and PBM wrapper containing the core logic (e.g. logic to whitelist the merchant&#x2F;redeemer address, logic to unwrap upon transfer to a whitelisted address, logic for minting and burning the PBM) and a token manager which allows for token registration, retrieval. In addition, the PBM wrapper &lt;strong&gt;MAY&lt;&#x2F;strong&gt; include logic to interface with plugins and hooks.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;plugin components&lt;&#x2F;strong&gt; implement additional functionality that only specific PBMs may require (e.g. logic to call external application programming interfaces to verify specific PBM condition was met, logic to track PBM usage patterns).&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;hook components&lt;&#x2F;strong&gt; implement additional validation checks that some PBMs may need (e.g. checks for expiration, daily spending limit, goods &amp;amp; services limit etc).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For example, a PBM creator may want to ensure that only 50% of PBM Series A can be spent in supermarkets, while there are no restrictions on the proportion of PBM Series B that can be spent in supermarkets. The creator can implement a plugin smart contract to keep track of supermarket spending by PBM users and a hook to validate that less than 50% of the PBM Series A issued to a user is spent in a supermarket. This approach allows the same generic PBM wrapper and sovToken to be used for both PBM Series A and B. In addition, PBM Series A will register the plugin module and hook module for additional data tracking and validations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;auditability&quot;&gt;Auditability&lt;&#x2F;h3&gt;
&lt;p&gt;PBM Wrapper &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; provide the public easily accessible mechanism(s) to verify the smart contract logic for unwrapping a PBM. Such mechanisms could be leveraged by automated validation or asynchronous user verifications from transacting parties and&#x2F;or whitelisted third parties attestations.&lt;&#x2F;p&gt;
&lt;p&gt;As the fulfilment of PBM conditions is likely to be subjected to audits to ensure trust amongst all transacting parties, the following evidence shall be documented to support audits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The interface&#x2F;events emitted &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; allow a fine-grained recreation of the transaction history, token types and token balances&lt;&#x2F;li&gt;
&lt;li&gt;The source code &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be verified and formally published on a blockchain explorer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;fungibility&quot;&gt;Fungibility&lt;&#x2F;h3&gt;
&lt;p&gt;A PBM Wrapper &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be able to wrap multiple types of compatible sovTokens (e.g. the same PBM Wrapper should be able to wrap USDC and XSGD). sovTokens wrapped by the same PBM wrapper may or may not be fungible to one another. The standard does NOT mandate how an implementation must do this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pbm-token-details&quot;&gt;PBM token details&lt;&#x2F;h3&gt;
&lt;p&gt;The ERC-1155 Multi Token Standard enables each token ID to correspond to a unique, configurable token type. All essential details facilitating the business or display logic for a PBM &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be defined for each token type. The mandatory fields for this purpose are outlined in the &lt;code&gt;struct PBMToken&lt;&#x2F;code&gt; (below). Future proposals may define additional, optional state variables as needed. Once a token detail has been defined, it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be immutable.&lt;&#x2F;p&gt;
&lt;p&gt;Example of token details:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IPBMRC1_TokenManager&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A PBM token MUST include compulsory state variables (name, faceValue, expiry, and uri) to adhere to this standard.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Represents all the details corresponding to a PBM tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PBMToken&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Name of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Value of the underlying wrapped ERC20-compatible sovToken. Additional information on the `faceValue` can be specified by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; adding the optional variables: `currencySymbol` or `tokenSymbol` as indicated below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; faceValue&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Time after which the token will be rendered useless (expressed in Unix Epoch time).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Metadata URI for ERC-1155 display purposes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; uri&lt;&#x2F;span&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;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;An implementer of the standard can enhance their PBM tokens with additional functionality by implementing the &lt;code&gt;IPBMRC1_TokenManagerExt&lt;&#x2F;code&gt; interface. This extension provides optional properties that can be used to support a variety of use cases beyond the core requirements.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IPBMRC1_TokenManagerExt&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Optional properties that a PBM token MAY include for extended functionality.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Represents additional optional fields that can be implemented for a PBM tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PBMTokenExt&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates if the PBM token can be transferred to a non merchant&#x2F;redeemer wallet.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; isTransferable&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Determines whether the PBM will be burned or revoked upon expiry, under certain predefined conditions, or at the owner&amp;#39;s discretion.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; burnable&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of decimal places for the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span&gt; decimals&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the creator of this PBM type on this smart contract. This field is optional because the creator is msg.sender by default.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; creator&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The smart contract address of the sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The running balance of the PBM Token type that has been minted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; totalSupply&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An ISO4217 three-character alphabetic code may be needed for the faceValue in multicurrency PBM use cases.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; currencySymbol&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An abbreviation for the PBM token name may be assigned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; tokenSymbol&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add other optional state variables below...&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;An implementer has the option to define all token types upon PBM contract deployment. If needed, they can also expose an external function to create new PBM tokens at a later time.
All token types created &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; emit a &lt;code&gt;NewPBMTypeCreated&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Creates a new PBM Token type with the provided data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The caller of createPBMTokenType shall be responsible for setting the creator address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example of uri can be found in [`sample-uri`](.&#x2F;assets&#x2F;sample-uri&#x2F;stx-10-static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST Emit the {NewPBMTypeCreated} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Name of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _faceValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Value of the underlying wrapped ERC20-compatible sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenExpiry&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Time after which the token will be rendered useless (expressed in Unix Epoch time).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Metadata URI for ERC-1155 display purposes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createPBMTokenType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _faceValue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenExpiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenURI&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a new Purpose-Bound Token (PBM) type is created within the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique identifier for the newly created PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenName&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A human-readable string representing the name of the newly created PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The initial supply of the newly created PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expiry&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The timestamp at which the newly created PBM token type will expire.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; creator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the account that created the new PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NewPBMTypeCreated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenName&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expiry&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; creator&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Implementors of the standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; define a method to retrieve a PBM token detail&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the details of a PBM Token type given its tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function fetches the PBMToken struct associated with the tokenId and returns it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; pbmToken_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A PBMToken struct containing all the details of the specified PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTokenDetails&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;PBMToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pbmToken_&lt;&#x2F;span&gt;&lt;span&gt;)&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;compliance-guard&quot;&gt;Compliance Guard&lt;&#x2F;h3&gt;
&lt;p&gt;A compliance guard should have logic to store and retrieve whitelisted merchants&#x2F;redeemers and blacklisted addresses to fulfill the basic premise of a PBM. Additional logic can be added to fulfill other compliance goals.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compliance Guard Interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The compliance guard stores and manages whitelisted merchants&#x2F;redeemers and blacklisted addresses for the PBMs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IComplianceGuard&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks if the address is one of the blacklisted addresses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if address is blacklisted, else false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isBlacklisted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bool_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks if the address is one of the whitelisted merchant&#x2F;redeemer addresses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the address is in merchant&#x2F;redeemer whitelist and is NOT a blacklisted address, otherwise false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isMerchant&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bool_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when the Merchant&#x2F;Redeemer List is edited&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; action&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Tags &amp;quot;add&amp;quot; or &amp;quot;remove&amp;quot; for action type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of merchant wallet addresses that was just added or removed from Merchant&#x2F;Redeemer whitelist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Optional comments or notes about the added or removed addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MerchantList&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; action&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadata&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event emitted when the Blacklist is edited&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; action&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Tags &amp;quot;add&amp;quot; or &amp;quot;remove&amp;quot; for action type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of wallet addresses that was just added or removed from address blacklist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Optional comments or notes about the added or removed addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Blacklist&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; action&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadata&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;pbmrc1-base-interface&quot;&gt;PBMRC1 - Base Interface&lt;&#x2F;h3&gt;
&lt;p&gt;This interface contains the essential functions required to implement a pre-loaded PBM.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; LIST OF EVENTS TO BE EMITTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A database or explorer may listen to events and be able to provide indexed and categorized searches&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; PBM Specification interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The PBM (purpose bound money) allows us to add logical requirements on the use of sovTokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The PBM acts as wrapper around the sovTokens and implements the necessary business logic.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; PBM deployer must assign an overall owner to the smart contract. If fine grain access controls are required, EIP-5982 can be used on top of ERC173&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IPBMRC1&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC173&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC5679Ext1155&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initialise the contract by specifying an underlying ERC20-compatible token address,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; contract expiry and PBM Wrapper Logic smart contract&amp;#39;s address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _expiry&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The contract-wide expiry timestamp (in Unix epoch time).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _pbmWrapperLogic&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This address should point to a smart contract that contains conditions governing a PBM;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; such as purpose-bound conditions (e.g., a compliance guard determining whether a PBM is permitted to be transferred or to be unwrapped)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; and other relevant business logic, effectively implementing an inversion of control.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initialise&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _sovToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _expiry&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _pbmWrapperLogic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the Uniform Resource Identifier (URI) metadata information for the PBM with the corresponding tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; URIs are defined in RFC 3986.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The URI MUST point to a JSON file that conforms to the &amp;quot;ERC-1155 Metadata URI JSON Schema&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Developers may choose to adhere to the ERC1155Metadata_URI extension interface if necessary.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The URI is not expected to be immutable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id for the PBM in query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the metadata URI string for the PBM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; uri&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Creates a PBM copy ( ERC1155 NFT ) of an existing PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC5679Ext1155} for further implementation notes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The wallet address to which the created PBMs need to be transferred to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type to be copied.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of the PBMs that are to be created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, based on EIP-5750&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 class=&quot;z-comment&quot;&gt;        This function transfers the underlying token from the caller into the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        IMPT: Before minting, the caller should approve the contract address to spend sovTokens on behalf of the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            This can be done by calling the `approve` or `increaseMinterAllowance` functions of the ERC-20 contract and specifying `_spender` to be the PBM contract address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            Ref : https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-20&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 class=&quot;z-comment&quot;&gt;        WARNING: Any contracts that externally call these safeMint() and safeMintBatch() functions should implement some sort of reentrancy guard procedure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        (such as OpenZeppelin&amp;#39;s ReentrancyGuard) or a Checks-effects-interactions pattern.&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 class=&quot;z-comment&quot;&gt;        As per ERC-5679 standard: When the token is being minted, the transfer events MUST be emitted as if the token in the `amount` for EIP-1155&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        and `tokenId` being _id for EIP-1155 were transferred from address 0x0 to the recipient address identified by receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The total supply MUST increase accordingly.&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 class=&quot;z-comment&quot;&gt;        MUST Emit the {TokenWrap} event as the underlying sovToken is wrapped by the PBM wrapper smart contract during minting.&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 class=&quot;z-comment&quot;&gt;        Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - contract must not be paused&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - tokens must not be expired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `tokenId` should be a valid id that has already been created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - caller should have the necessary amount of the sovTokens required to mint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - caller should have approved the PBM contract to spend the sovTokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - receiver should not be blacklisted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Creates multiple PBM copies (ERC1155 NFT) of an existing PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC5679Ext1155}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The wallet address to which the created PBMs need to be transferred to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of the PBMs that are to be created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, based on eip-5750&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 class=&quot;z-comment&quot;&gt;        This function will transfer the underlying token from the caller into the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        IMPT: Before minting, the caller should approve the contract address to spend sovTokens on behalf of the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            This can be done by calling the `approve` or `increaseMinterAllowance` functions of the ERC-20 contract and specifying `_spender` to be the PBM contract address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            Ref : https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-20&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 class=&quot;z-comment&quot;&gt;        WARNING: Any contracts that externally call these safeMint() and safeMintBatch() functions should implement some sort of reentrancy guard procedure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        (such as OpenZeppelin&amp;#39;s ReentrancyGuard) or a Checks-effects-interactions pattern.&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 class=&quot;z-comment&quot;&gt;        As per ERC-5679 standard: When the token is being minted, the transfer events MUST be emitted as if the token in the `amount` for EIP-1155&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        and `tokenId` being _id for EIP-1155 were transferred from address 0x0 to the recipient address identified by receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The total supply MUST increase accordingly.&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 class=&quot;z-comment&quot;&gt;        MUST Emit the {TokenWrap} event as the underlying sovToken is wrapped by PBM wrapper smart contract during minting.&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 class=&quot;z-comment&quot;&gt;        Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - contract must not be paused&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - tokens must not be expired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `tokenIds` should all be valid ids that have already been created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `tokenIds` and `amounts` list need to have the same number of values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - caller should have the necessary amount of the sovTokens required to mint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - caller should have approved the PBM contract to spend the sovTokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - receiver should not be blacklisted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMintBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Burns a PBM token. Upon burning of the tokens, the underlying wrapped token (if any) should be handled.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Destroys `amount` tokens of token type `tokenId` from `from`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC5679Ext1155}&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 class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The originating wallet address of the PBMs to be burned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the PBMs that are to be burned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, based on EIP-5750&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 class=&quot;z-comment&quot;&gt;        MUST Emit the {TransferSingle} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST Emit the {TokenUnwrapForPBMBurn} event if the underlying wrapped token is moved out of the PBM smart contract.&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 class=&quot;z-comment&quot;&gt;        Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `from` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `from` must have at least `amount` tokens of token type `tokenId`.&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 class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Burns multiple PBM token. Upon burning of the tokens, the underlying wrapped token (if any) should be handled.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Destroys `amount` tokens of token type `tokenId` from `from`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC5679Ext1155}&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 class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The originating wallet address of the PBMs to be burned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token types&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the PBMs that are to be burned for each tokenId in _tokenIds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, based on eip-5750&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 class=&quot;z-comment&quot;&gt;        MUST Emit the {TransferSingle} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST Emit the {TokenUnwrapForPBMBurn} event if the underlying wrapped token is moved out of the PBM smart contract.&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 class=&quot;z-comment&quot;&gt;        Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `from` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        - `from` must have at least amount specified in `_amounts` of the corresponding token type tokenId in `_tokenIds` array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burnBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers the PBM(NFT) from one wallet to another.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function extends the ERC-1155 standard in order to allow the PBM token to be freely transferred between wallet addresses due to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; widespread support across wallet providers. Specific conditions and restrictions on whether a pbm can be moved across addresses can be incorporated in this function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unwrap logic MAY also be placed within this function to be called.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account from which the PBM (NFT) is moving from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account which is receiving the PBM (NFT)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of (quantity) the PBM type that are to be transferred of the PBM type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; To record any data associated with the transaction, can be left blank if none&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers the PBM(NFT)(s) from one wallet to another.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function extends the ERC-1155 standard in order to allow the PBM token to be freely transferred between wallet addresses due to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; widespread support across wallet providers.  Specific conditions and restrictions on whether a pbm can be moved across addresses can be incorporated in this function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unwrap logic MAY also be placed within this function to be called.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the receiving wallet is a whitelisted &#x2F;redeemer wallet address, the PBM(NFT)(s) will be burnt and the underlying sovTokens will be transferred to the merchant&#x2F;redeemer wallet instead.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account from which the PBM (NFT)(s) is moving from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account which is receiving the PBM (NFT)(s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifiers of the different PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of (quantity) the different PBM types that are to be created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; To record any data associated with the transaction, can be left blank if none.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeBatchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unwraps the underlying ERC-20 compatible tokens to an intended end point (ie: merchant&#x2F;redeemer) upon fulfilling the required PBM conditions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add implementation specific logic for the conditions under which a PBM processes and transfers the underlying tokens here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; e.g. If the receiving wallet is a whitelisted merchant&#x2F;redeemer wallet address, the PBM (NFT) MUST be burnt and the underlying sovTokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; will unwrapped to be transferred to the merchant&#x2F;redeemer wallet.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST Emit the {TokenUnwrapForTarget} event on success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account currently holding the PBM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account receiving the PBM (NFT)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The quantity of the PBM type involved in this transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data without a specified format, based on EIP-5750&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unwrap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allows the creator of a PBM token type to retrieve all locked-up underlying sovTokens within that PBM.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure that only the creator of the PBM token type or the contract owner can call this function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Validate the token state and existence, handle PBM token burning if necessary, safely transfer the remaining sovTokens to the originator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST Emit the {PBMrevokeWithdraw} event upon a successful revoke.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` should be a valid identifier for an existing PBM token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The caller must be either the creator of the token type or the smart contract owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokePBM&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a PBM type creator withdraws the underlying sovTokens from all the remaining expired PBMs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; beneficiary&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address ( PBM type creator ) which receives the sovToken&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; PBMTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifiers of the different PBM token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of underlying sovTokens transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PBMrevokeWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; beneficiary&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; PBMTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the underlying tokens are unwrapped and transferred to a specific purpose-bound address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event signifies the end of the PBM lifecycle, as all necessary conditions have been met to release the underlying tokens to the recipient (whitelisted merchant&#x2F;redeemer with non-blacklisted wallet address).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If there are multiple different underlying tokens involved in a single unwrap operation, this event should be emitted for each underlying token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address from which the PBM tokens are being unwrapped.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The purpose-bound address receiving the unwrapped underlying tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the identifiers of the unwrapped PBM token types.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the quantities of the corresponding unwrapped PBM tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of unwrapped underlying sovTokens transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUnwrapForTarget&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when PBM tokens are burned, resulting in the unwrapping of the underlying tokens for the designated recipient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event is required if there is an unwrapping of the underlying tokens during the PBM (NFT) burning process.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If there are multiple different underlying tokens involved in a single unwrap operation, this event should be emitted for each underlying token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address from which the PBM tokens are being burned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address receiving the unwrapped underlying tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the identifiers of the burned PBM token types.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the quantities of the corresponding burned PBM tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of unwrapped underlying sovTokens transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUnwrapForPBMBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates the wrapping of a token into the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when underlying tokens are wrapped within the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If there are multiple different underlying tokens involved in a single wrap operation, this event should be emitted for each underlying token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event signifies the beginning of the PBM lifecycle, as tokens are now managed by the conditions within the PBM contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address initiating the token wrapping process, and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the identifiers of the token types being wrapped.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array containing the quantities of the corresponding wrapped tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of wrapped underlying sovTokens transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenWrap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;extensions&quot;&gt;Extensions&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;pbmrc1-token-receiver&quot;&gt;PBMRC1 - Token Receiver&lt;&#x2F;h4&gt;
&lt;p&gt;Smart contracts MUST implement all of the functions in the PBMRC1_TokenReceiver interface to subscribe to PBM unwrap callbacks.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Smart contracts MUST implement the ERC-165 `supportsInterface` function and signify support for the `PBMRC1_TokenReceiver` interface to accept callbacks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is optional for a receiving smart contract to implement the `PBMRC1_TokenReceiver` interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WARNING: Reentrancy guard procedure, Non delegate call, or the check-effects-interaction pattern must be adhere to when calling an external smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface functions MUST only be called at the end of the `unwrap` function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PBMRC1_TokenReceiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handles the callback from a PBM smart contract upon unwrapping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An PBM smart contract MUST call this function on the token recipient contract, at the end of a `unwrap` if the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        receiver smart contract supports type(PBMRC1_TokenReceiver).interfaceId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address which initiated the transfer (either the address which previously owned the token or the address authorised to make transfers on the owner&amp;#39;s behalf) (i.e. msg.sender)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The address which previously owned the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The ID of the token being unwrapped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The amount of tokens being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           `bytes4(keccak256(&amp;quot;onPBMRC1Unwrap(address,address,uint256,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onPBMRC1Unwrap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handles the callback from a PBM smart contract upon unwrapping a batch of tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A PBM smart contract MUST call this function on the token recipient contract at the end of an `unwrap` if the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        receiver smart contract supports type(PBMRC1_TokenReceiver).interfaceId&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 class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address which initiated the transfer (either the address which previously owned the token or the address authorised to make transfers on the owner&amp;#39;s behalf) (i.e. msg.sender)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The address which previously owned the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The ID of the token being unwrapped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The amount of tokens being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           `bytes4(keccak256(&amp;quot;onPBMRC1BatchUnwrap(address,address,uint256,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onPBMRC1BatchUnwrap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;pbmrc2-non-preloaded-pbm-interface&quot;&gt;PBMRC2 - Non preloaded PBM Interface&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;strong&gt;Non Preloaded&lt;&#x2F;strong&gt; PBM extension is OPTIONAL for compliant smart contracts. This allows contracts to bind an underlying sovToken to the PBM at a later date instead of during a minting process.&lt;&#x2F;p&gt;
&lt;p&gt;Compliant contract &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This interface extends IPBMRC1, adding functions for working with non-preloaded PBMs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  Non-preloaded PBMs are minted as empty containers without any underlying tokens of value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  allowing the loading of the underlying token to happen at a later stage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PBMRC2_NonPreloadedPBM&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IPBMRC1&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function extends IPBMRC1 to mint PBM tokens as empty containers without underlying tokens of value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The loading of the underlying token of value can be done by calling the `load` function. The function parameters should be identical to IPBMRC1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function extends IPBMRC1 to mint PBM tokens as empty containers without underlying tokens of value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The loading of the underlying token of value can be done by calling the `load` function. The function parameters should be identical to IPBMRC1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMintBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Wrap an amount of sovTokens into the PBM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; function will pull sovTokens from msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approval must be given to the PBM smart contract in order to for the pbm to pull money from msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; underlying data structure must record how much the msg.sender has been loaded into the PBM.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits {TokenLoad} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The amount of sovTokens to be loaded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; load&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the balance of the underlying sovToken associated with a specific PBM token type and user address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function provides a way to check the amount of the underlying token that a user has loaded into a particular PBM token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the user whose underlying token balance is being queried.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; balance of the underlying sovToken associated with the specified PBM token type and user address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; underlyingBalanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unloads all of the underlying token belonging to the caller from the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The underlying token that belongs to the caller (msg.sender) will be removed and transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; back to the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits {TokenUnload} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The quantity of the corresponding tokens to be unloaded.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Amount should not exceed the amount that the caller has originally loaded into the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an underlying token is loaded into a PBM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address by which sovToken is taken from.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address by which the token is loaded and assigned to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The quantity of tokens to be loaded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of underlying sovTokens loaded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenLoad&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; caller&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an underlying token is unloaded from a PBM.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event indicates the process of releasing the underlying token from the PBM smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address initiating the token unloading process.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address from which the token is being unloaded and removed from.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The quantity of the corresponding unloaded tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the underlying sovToken.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of unloaded underlying sovTokens transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUnload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; caller&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovToken&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sovTokenValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-sovtoken-must-be-erc-20-compatible&quot;&gt;Why sovToken &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be ERC-20 compatible?&lt;&#x2F;h3&gt;
&lt;p&gt;As PBM is envisioned to have functionality of money, it has to be a fungible token with stable value. Currently, the major stablecoins in the market are mainly based on the ERC-20 interface. ERC-20 or ERC-20 compatible tokens are the most widely supported by existing wallets, defi apps, and used also by protocol design such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; and more importantly they are the de facto standard for fungible tokens.&lt;&#x2F;p&gt;
&lt;p&gt;With regards to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and ERC-1155 compatible tokens:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ERC-721 is not suitable given that it is a standard for non-fungible tokens, which cannot fulfill the functions of money.&lt;&#x2F;li&gt;
&lt;li&gt;While ERC-1155 tokens could be used for fungible tokens, we decided not to include it because there is a lack of ERC-1155 stablecoins in the market. Requiring the PBM interface to support both ERC-20 compatible and ERC-1155 compatible sovToken would complicate PBM interface without adding much practical utility. Furthermore, the base ERC-1155 does not support decimals, but this is not a dealbreaker as there can be workarounds. However, should there be changes in the stablecoin market in future, a revision can be considered.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-pbm-wrapper-must-be-erc-1155-compatible&quot;&gt;Why PBM Wrapper &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be ERC-1155 compatible?&lt;&#x2F;h3&gt;
&lt;p&gt;This paper extends the ERC-1155 standards in order to enable easy adoption by existing wallet providers. Currently, most wallet providers are able to support and display ERC-20, ERC-1155 and ERC-721 standards. An implementation which doesn&#x27;t extend these standards will require the wallet provider to build a custom user interface and interfacing logic which increases the implementation cost and lengthen the time-to-market.&lt;&#x2F;p&gt;
&lt;p&gt;The core aim of our proposal is to standardize the implementation of PBM. Hence, we have surveyed existing interface standards and decided to build upon ERC-1155 standard for the PBM tokens for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ERC-1155 allows a single contract to support multiple tokens. This is very useful for the PBM use cases as a single contract can support issuance of tokens with different denominations, expiry dates, business logics.&lt;&#x2F;li&gt;
&lt;li&gt;ERC-1155 also has batch transfer support, which is absent in ERC-20, which could lead to gas savings when tokens have to be airdropped to a large number of recipients.&lt;&#x2F;li&gt;
&lt;li&gt;ERC-1155 is able to support semi-fungible tokens which could be very useful for PBM use cases as a PBM can be converted into a collectible after its expiry.&lt;&#x2F;li&gt;
&lt;li&gt;ERC-1155 allows for a visualisation of a PBM token on the UI of a wallet issuer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-pbm-must-ensure-the-destination-address-for-unwrapped-sovtoken-is-in-a-whitelist-of-merchant-redeemer-addresses-and-not-in-a-blacklist-of-banned-addresses-prior-to-unwrapping-the-underlying-sovtoken&quot;&gt;Why PBM &lt;strong&gt;MUST&lt;&#x2F;strong&gt; ensure the destination address for unwrapped sovToken is in a whitelist of Merchant&#x2F;Redeemer addresses and not in a blacklist of banned addresses prior to unwrapping the underlying sovToken?&lt;&#x2F;h3&gt;
&lt;p&gt;Why do we need a whitelist?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The whitelist is a compulsory requirement because a PBM is purpose-bound, i.e., it should be unwrapped only if all conditions are fulfilled and it is transferred to someone in the predefined whitelist.&lt;&#x2F;li&gt;
&lt;li&gt;In some implementations, developers can define a whitelisted address dynamically at runtime, such as requiring the presence of an NFT in a wallet address or relying on an oracle, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why do we need a blacklist?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The blacklist is a compulsory requirement to ensure that accounts which were banned for various reasons (e.g., address owner has re-registered a new account, address owner suspended, withdrawn, or expelled due to complaints or law enforcement reasons, etc.) are excluded.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why we can&#x27;t have either a whitelist or a blacklist?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;While the same effect can be obtained by only having a whitelist, repeatedly redeploying the whitelist to the blockchain to ban one person is not gas efficient.&lt;&#x2F;li&gt;
&lt;li&gt;Using only a blacklist to implement purpose-bound money is not practical as it would require maintaining a list of all addresses to be excluded and updating it whenever a new account is created.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why is there a need for destination?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This forms the core of our proposal: a PBM can be unwrapped when only it is transferred to pre-approved destinations.&lt;&#x2F;li&gt;
&lt;li&gt;PBMs can be transferred freely, but only the target is allowed to unwrap the PBM and take delivery of the underlying sovToken must be limited to differentiate it from plain vanilla stablecoins that are wrapped by smart contracts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;what-does-business-logic-encompass&quot;&gt;What does business logic encompass?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;In general, business logic can be categorized into core, plugin, and hook logic:
&lt;ul&gt;
&lt;li&gt;Core logic contains essential functionalities and validation checks and should be included in the PBM Wrapper contract.&lt;&#x2F;li&gt;
&lt;li&gt;Plugin and hook logic can be implemented as standalone smart contract modules and are registered by the PBM Wrapper contract. Plugin logic extends the core logic by adding functionality, e.g., custom data collection, additional administrative functions, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Hook logic implements additional validation checks which are only applicable for a subset of PBMs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;PBM business logic&quot; can contain access control logic, PBM unwrapping logic, API logic to integrate with non-blockchain IT systems.&lt;&#x2F;li&gt;
&lt;li&gt;As PBM can be used for a wide variety of use cases, ranging from government disbursement tokens, shopping vouchers, prepaid tokens, rewards points tokens, purpose-bound donation tokens, school allowance tokens, etc., with each use case having separate business logic, it was intentionally left undefined so that implementation authors can have maximum flexibility.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-was-a-push-transaction-model-chosen&quot;&gt;Why was a push transaction model chosen?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;This standard sticks to the push transaction model where the transfer of PBM is initiated on the sender&#x27;s side. Modern wallets can support the required PBM logic by embedding the unwrapping logic within the ERC-1155 &lt;code&gt;safeTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;customisability&quot;&gt;Customisability&lt;&#x2F;h3&gt;
&lt;p&gt;Each ERC-1155 PBM Token would map to an underlying &lt;code&gt;PBMToken&lt;&#x2F;code&gt; data structure that implementers are free to customize in accordance to the business logic.&lt;&#x2F;p&gt;
&lt;p&gt;By mapping the underlying ERC-1155 token model with an additional data structure, implementers gain flexibility in the management of multiple token types within the same smart contract with multiple conditional unwrapping logic attached to each token type, reducing gas costs as there is no need to deploy multiple smart contracts for each token type.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To keep it simple, this standard &lt;em&gt;intentionally&lt;&#x2F;em&gt; omits functions or events that doesn&#x27;t add to definition and concept of a PBM.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This EIP makes no assumptions about access control or the conditions under which a function can be executed. It is the responsibility of the PBM creator to determine the various roles involved in each specific PBM business flow.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The proposed PBM Architecture &lt;em&gt;intentionally&lt;&#x2F;em&gt; modular to enable greater customisability and reusability of smart contracts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Metadata associated to the PBM standard is not included the standard. If necessary, related metadata can be created with a separate metadata extension interface, e.g. &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; from ERC-721. Refer to Opensea&#x27;s metadata-standards for an implementation example.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To allow for future extensibility, it is &lt;strong&gt;RECOMMENDED&lt;&#x2F;strong&gt; that developers read and adopt the specifications for building general extensibility for method behaviours (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5750&#x2F;&quot;&gt;ERC-5750&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This interface is designed to be compatible with ERC-1155.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Reference implementations can be found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7291&#x2F;assets&#x2F;README&#x2F;&quot;&gt;&lt;code&gt;README.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Malicious users may attempt to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Double spend through reentrancy.&lt;&#x2F;li&gt;
&lt;li&gt;clone existing PBM Tokens to perform double-spending;&lt;&#x2F;li&gt;
&lt;li&gt;create invalid PBM Token with no underlying sovToken; or&lt;&#x2F;li&gt;
&lt;li&gt;falsifying the face value of PBM token through wrapping of fraudulent&#x2F;invalid&#x2F;worthless sovTokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For consistency, when the contract is suspended or a user&#x27;s token transfer is restricted due to suspected fraudulent activity or erroneous transfers, corresponding restrictions &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be applied to the user&#x27;s unwrap requests for the PBM Token.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Security audits and tests should be performed to verify that unwrap logic behaves as expected or if any complex business logic is being implemented that involves calling an external smart contract to prevent re-entrancy attacks and other forms of call chain attacks.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This EIP relies on the secure and accurate bookkeeping behavior of the token implementation.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Contracts adhering to this standard should closely monitor balance changes for each user during token consumption or minting.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The PBM Wrapper must be meticulously designed to ensure effective control over the permission to mint new tokens. Failure to secure the minting permission can lead to fraudulent issuance and unauthorized inflation of the total token supply.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The mapping of each PBM Token to the corresponding amount of underlying sovToken held by the smart contract requires careful accounting and auditing.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The access control over permission to burn tokens should be carefully designed. Typically, only the following two roles are entitled to burn a token:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Role 1. Prior to a PBM&#x27;s expiry, only whitelisted merchants&#x2F;redeemers with non-blacklisted wallet addresses are allowed to unwrap and burn tokens that they hold.&lt;&#x2F;li&gt;
&lt;li&gt;Role 2. After a PBM has expired:
&lt;ul&gt;
&lt;li&gt;whitelisted merchants&#x2F;redeemers with non-blacklisted wallet addresses are allowed to unwrap and burn tokens that they hold; and&lt;&#x2F;li&gt;
&lt;li&gt;PBM owners are allowed to burn unused PBM Tokens remaining in the hands of non-whitelisted merchants&#x2F;redeemers to retrieve underlying sovTokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Nevertheless, we do recognize there are potentially other use cases where a third type of role may be entitled to burning. Implementors should be cautious when designing access control over burning of PBM Tokens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It is recommended to adopt a sovToken standard that is compatible with ERC-20. Examples of such compatible tokens include those implementing ERC-777 or ERC-1363. However, ERC-20 remains the most widely accepted due to its simplicity and there is a high degree of confidence in its security.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Namespaced Storage Layout</title>
        <published>2023-06-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	<author>
		<name>Ernesto García</name><uri>https://github.com/ernestognw</uri>
	</author>
	
	<author>
		<name>Eric Lau</name><uri>https://github.com/ericglau</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7201/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7201-namespaced-storage-layout/14796" />
        

        <id>https://wg-eips.ritovision.com/7201/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7201"
            label="ERC-7201" />
        

        
        

        
        <summary type="html">Conventions for the storage location of structs in the namespaced storage pattern.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7201/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;We define the NatSpec annotation &lt;code&gt;@custom:storage-location&lt;&#x2F;code&gt; to document storage namespaces and their location in storage in Solidity or Vyper source code. Additionally, we define a formula to derive a location from an arbitrary identifier. The formula is chosen to be safe against collisions with the storage layouts used by Solidity and Vyper.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Smart contract languages such as Solidity and Vyper rely on tree-shaped storage layout. This tree starts at slot 0 and is composed of sequential chunks for consecutive variables. Hashes are used to ensure the chunks containing values of mappings and dynamic arrays do not collide. This is sufficient for most contracts. However, it presents a challenge for various design patterns used in smart contract development. One example is a modular design where using &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; a contract executes code from multiple contracts, all of which share the same storage space, and which have to carefully coordinate on how to use it. Another example is upgradeable contracts, where it can be difficult to add state variables in an upgrade given that they may affect the assigned storage location for the preexisting variables.&lt;&#x2F;p&gt;
&lt;p&gt;Rather than using this default storage layout, these patterns can benefit from laying out state variables across the storage space, usually at pseudorandom locations obtained by hashing. Each value may be placed in an entirely different location, but more frequently values that are used together are put in a Solidity struct and co-located in storage. These pseudorandom locations can be the root of new storage trees that follow the same rules as the default one. Provided that this pseudorandom root is constructed so that it is not part of the default tree, this should result in the definition of independent spaces that do not collide with one another or with the default one.&lt;&#x2F;p&gt;
&lt;p&gt;These storage usage patterns are invisible to the Solidity and Vyper compilers because they are not represented as Solidity state variables. Smart contract tools like static analyzers or blockchain explorers often need to know the storage location of contract data. Standardizing the location for storage layouts will allow these tools to correctly interpret contracts where these design patterns are used.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;preliminaries&quot;&gt;Preliminaries&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;em&gt;namespace&lt;&#x2F;em&gt; consists of a set of ordered variables, some of which may be dynamic arrays or mappings, with its values laid out following the same rules as the default storage layout but rooted in some location that is not necessarily slot 0. A contract using namespaces to organize storage is said to use &lt;em&gt;namespaced storage&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;em&gt;namespace id&lt;&#x2F;em&gt; is a string that identifies a namespace in a contract. It should not contain any whitespace characters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;custom-storage-location&quot;&gt;&lt;code&gt;@custom:storage-location&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A namespace in a contract should be implemented as a struct type. These structs should be annotated with the NatSpec tag &lt;code&gt;@custom:storage-location &amp;lt;FORMULA_ID&amp;gt;:&amp;lt;NAMESPACE_ID&amp;gt;&lt;&#x2F;code&gt;, where &lt;code&gt;&amp;lt;FORMULA_ID&amp;gt;&lt;&#x2F;code&gt; identifies a formula used to compute the storage location where the namespace is rooted, based on the namespace id. &lt;em&gt;(Note: The Solidity compiler includes this annotation in the AST since v0.8.20, so this is recommended as the minimum compiler version when using this pattern.)&lt;&#x2F;em&gt; Structs with this annotation found outside of contracts are not considered to be namespaces for any contract in the source code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;formula&quot;&gt;Formula&lt;&#x2F;h3&gt;
&lt;p&gt;The formula identified by &lt;code&gt;erc7201&lt;&#x2F;code&gt; is defined as &lt;code&gt;erc7201(id: string) = keccak256(keccak256(id) - 1) &amp;amp; ~0xff&lt;&#x2F;code&gt;. In Solidity, this corresponds to the expression &lt;code&gt;keccak256(abi.encode(uint256(keccak256(bytes(id))) - 1)) &amp;amp; ~bytes32(uint256(0xff))&lt;&#x2F;code&gt;. When using this formula the annotation becomes &lt;code&gt;@custom:storage-location erc7201:&amp;lt;NAMESPACE_ID&amp;gt;&lt;&#x2F;code&gt;. For example, &lt;code&gt;@custom:storage-location erc7201:foobar&lt;&#x2F;code&gt; annotates a namespace with id &lt;code&gt;&quot;foobar&quot;&lt;&#x2F;code&gt; rooted at &lt;code&gt;erc7201(&quot;foobar&quot;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Future EIPs may define new formulas with unique formula identifiers. It is recommended to follow the convention set in this EIP and use an identifier of the format &lt;code&gt;erc1234&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The tree-shaped storage layout used by Solidity and Vyper follows the following grammar (with root=0):&lt;&#x2F;p&gt;
&lt;p&gt;$L_{root} := \mathit{root} \mid L_{root} + n \mid \texttt{keccak256}(L_{root}) \mid \texttt{keccak256}(H(k) \oplus L_{root}) \mid \texttt{keccak256}(L_{root} \oplus H(k))$&lt;&#x2F;p&gt;
&lt;p&gt;A requirement for the root is that it shouldn&#x27;t overlap with any storage location that would be part of the standard storage tree used by Solidity and Vyper (root = 0), nor should it be part of the storage tree derived from any other namespace (another root). This is so that multiple namespaces may be used alongside each other and alongside the standard storage layout, either deliberately or accidentally, without colliding. The term &lt;code&gt;keccak256(id) - 1&lt;&#x2F;code&gt; in the formula is chosen as a location that is unused by Solidity, but this is not used as the final location because namespaces can be larger than 1 slot and would extend into &lt;code&gt;keccak256(id) + n&lt;&#x2F;code&gt;, which is potentially used by Solidity. A second hash is added to prevent this and guarantee that namespaces are completely disjoint from standard storage, assuming keccak256 collision resistance and that arrays are not unreasonably large.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, namespace locations are aligned to 256 as a potential optimization, in anticipation of gas schedule changes after the Verkle state tree migration, which may cause groups of 256 storage slots to become warm all at once.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;naming&quot;&gt;Naming&lt;&#x2F;h3&gt;
&lt;p&gt;This pattern has sometimes been referred to as &quot;diamond storage&quot;. This causes it to be conflated with the &quot;diamond proxy pattern&quot;, even though they can be used independently of each other. This EIP has chosen to use a different name to clearly differentiate it from the proxy pattern.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @custom:storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-location erc7201:example.main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MainStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256(abi.encode(uint256(keccak256(&amp;quot;example.main&amp;quot;)) - 1)) &amp;amp; ~bytes32(uint256(0xff));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; MAIN_STORAGE_LOCATION &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getMainStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;MainStorage&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; MAIN_STORAGE_LOCATION&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getXTimesY&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;        MainStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; $ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getMainStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Namespaces should avoid collisions with other namespaces or with standard Solidity or Vyper storage layout. The formula defined in this ERC guarantees this property for arbitrary namespace ids under the assumption of keccak256 collision resistance, as discussed in Rationale.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;@custom:storage-location&lt;&#x2F;code&gt; is a NatSpec annotation that current compilers don&#x27;t enforce any rules for or ascribe any meaning to. The contract developer is responsible for implementing the pattern and using the namespace as claimed in the annotation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC-721 Multi-Metadata Extension</title>
        <published>2023-06-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>0xG</name><uri>https://github.com/0xGh</uri>
	</author>
	
	<author>
		<name>Marco Peyfuss</name><uri>https://github.com/mpeyfuss</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7160/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc721-multi-metadata-extension/14629" />
        

        <id>https://wg-eips.ritovision.com/7160/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7160"
            label="ERC-7160" />
        

        
        

        
        <summary type="html">Multiple metadata URIs per token, with the option to pin a primary URI.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7160/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes an extension to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard to support multiple metadata URIs per token. It introduces a new interface, &lt;code&gt;IERC721MultiMetadata&lt;&#x2F;code&gt;, which provides methods for accessing the metadata URIs associated with a token, including a pinned URI index and a list of all metadata URIs. The extension is designed to be backward compatible with existing &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The current &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard allows for a single metadata URI per token with the &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; implementation. However, there are use cases where multiple metadata URIs are desirable. Some example use cases are listed below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A token represents a collection of (cycling) assets with individual metadata&lt;&#x2F;li&gt;
&lt;li&gt;An on-chain history of revisions to token metadata&lt;&#x2F;li&gt;
&lt;li&gt;Appending metadata with different aspect ratios so that it can be displayed properly on all screens&lt;&#x2F;li&gt;
&lt;li&gt;Dynamic and evolving metadata&lt;&#x2F;li&gt;
&lt;li&gt;Collaborative and multi-artist tokens&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This extension enables such use cases by introducing the concept of multi-metadata support.&lt;&#x2F;p&gt;
&lt;p&gt;The primary reason for having a multi-metadata standard in addition to the existing &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; standard is that dapps and marketplaces don&#x27;t have a mechanism to infer and display all the token URIs. Giving a standard way for marketplaces to offer collectors a way to pin&#x2F;unpin one of the metadata choices also enables quick and easy adoption of this functionality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The multi-metadata extension is OPTIONAL for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; contracts and it is RECOMMENDED to be used in conjunction with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4906&#x2F;&quot;&gt;ERC-4906&lt;&#x2F;a&gt; standard if implemented&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-721 Multi-Metdata Extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ERC-165 identifier for this interface is 0x06e1bc5b.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7160&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when a token uri is pinned and is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  useful for indexing purposes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUriPinned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when a token uri is unpinned and is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  useful for indexing purposes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUriUnpinned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get all token uris associated with a particular token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If a token uri is pinned, the index returned SHOULD be the index in the string array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST revert if the token does not exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for the nft&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An unisgned integer that specifies which uri is pinned for a token (or the default uri if unpinned)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uris&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A string array of all uris associated with a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean showing if the token has pinned metadata or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uris&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Pin a specific token uri for a particular token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST revert if the token does not exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST emit a `TokenUriPinned` event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MAY emit a `MetadataUpdate` event from ERC-4096&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the nft&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index in the string array returned from the `tokenURIs` function that should be pinned for the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pinTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unpin metadata for a particular token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST revert if the token does not exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST emit a `TokenUriUnpinned` event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MAY emit a `MetadataUpdate` event from ERC-4096&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is up to the developer to define what this function does and is intentionally left open-ended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the nft&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unpinTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check on-chain if a token id has a pinned uri or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This call MUST revert if the token does not exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Useful for on-chain mechanics that don&amp;#39;t require the tokenURIs themselves&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier of the nft&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A bool specifying if a token has metadata pinned or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;TokenUriPinned&lt;&#x2F;code&gt; event MUST be emitted when pinning a token uri with the &lt;code&gt;pinTokenUri&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;TokenUriUnpinned&lt;&#x2F;code&gt; event MUST be emitted when unpinning a token uri with the &lt;code&gt;unpinTokenUri&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;tokenURI&lt;&#x2F;code&gt; function defined in the ERC-721 Metadata extension MUST return the pinned URI when a token has a pinned uri.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;tokenURI&lt;&#x2F;code&gt; function defined in the ERC-721 Metadata extension MUST return a default uri when a token has an unpinned uri.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0x06e1bc5b&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Implementing functionality to add or remove uris to a token MUST be implemented separately from this standard. It is RECOMMENDED that one of the event defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4906&#x2F;&quot;&gt;ERC-4906&lt;&#x2F;a&gt; are emitted whenever uris are added or removed.&lt;&#x2F;p&gt;
&lt;p&gt;See the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7160&#x2F;#reference-implementation&quot;&gt;Implementation&lt;&#x2F;a&gt; section for an example.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Similar terminology to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; was used in order to keep fetching metadata familiar. The concept of pinning and unpinning metadata is introduced as it is clear that NFT owners might want to choose which piece of metadata to display. At first, we considered leaving the pinning and unpinning actions up to each developer, but realized that a standard interface for pinning and unpinning allows for dApps to easily implement universal support for multi-metadata tokens.&lt;&#x2F;p&gt;
&lt;p&gt;We first considered whether the &lt;code&gt;tokenURIs&lt;&#x2F;code&gt; function should return just a string array, but added the extra information so that you could get all info desired in one call instead of potentially three calls. The pinned URI should be used as the primary URI for the token, while the list of metadata URIs can be used to access individual assets&#x27; metadata within the token. dApps could present these as a gallery or media carousels.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;TokenUriPinned&lt;&#x2F;code&gt; and &lt;code&gt;TokenUriUnpinned&lt;&#x2F;code&gt; events included in this specification can be used by dApps to index what metadata to show. This can eliminate on-chain calls and event driven architecture can be used instead.&lt;&#x2F;p&gt;
&lt;p&gt;The reason why this standard recommends the use of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4906&#x2F;&quot;&gt;ERC-4906&lt;&#x2F;a&gt; when adding or removing uris from a token is that there is already wide dApp support for this event and it already is what is needed - an alert to dApps that metadata for a token has been updated. We did not want to potentially cause dApp issues with duplicate events. A third party listening to this event could then call the &lt;code&gt;tokenURIs&lt;&#x2F;code&gt; function to get the updated metadata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This extension is designed to be backward compatible with existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; contracts. The implementation of the &lt;code&gt;tokenURI&lt;&#x2F;code&gt; method must either return the pinned token uri (if pinned) or some default uri (if unpinned).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;An open-source reference implementation of the &lt;code&gt;IERC721MultiMetadata&lt;&#x2F;code&gt; interface can be provided, demonstrating how to extend an existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; contract to support multi-metadata functionality. This reference implementation can serve as a guide for developers looking to implement the extension in their own contracts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Ownable&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;access&#x2F;Ownable.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC4906&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;interfaces&#x2F;IERC4906.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7160&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC7160.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MultiMetadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Ownable&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC7160&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC4906&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _pinnedURIIndices&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _hasPinnedTokenURI&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_name, _symbol) &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Ownable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice Returns the pinned URI index or the last token URI index (length - 1).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getTokenURIIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; _hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; _pinnedURIIndices&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice Implementation of ERC721.tokenURI for backwards compatibility.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @inheritdoc ERC721.tokenURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    _requireMinted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getTokenURIIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; uris &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; uri &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; uris&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revert if no URI is found for the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;uri&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC721: not URI found&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; uri&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC721MultiMetadata.tokenURIs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uris&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    _requireMinted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_getTokenURIIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC721MultiMetadata.pinTokenURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pinTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Unauthorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    _pinnedURIIndices&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUriPinned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC721MultiMetadata.unpinTokenURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unpinTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Unauthorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    _pinnedURIIndices&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    _hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUriUnpinned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @inheritdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IERC721MultiMetadata.hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pinned&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; _hasPinnedTokenURI&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets a specific metadata URI for a token at the given index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setUri&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uri&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span&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&gt;      _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; uri&lt;&#x2F;span&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;span class=&quot;z-keyword&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&gt;      _tokenURIs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;uri&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MetadataUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Overrides supportsInterface to include IERC721MultiMetadata interface support.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC165&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC7160&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;      super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Care should be taken when specifying access controls for state changing events, such as those that allow uris to be added to tokens
and those specified in this standard: the &lt;code&gt;pinTokenUri&lt;&#x2F;code&gt; and &lt;code&gt;unpinTokenUri&lt;&#x2F;code&gt; functions. This is up to the developers to specify
as each application may have different requirements to allow for pinning and unpinning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>On-Chain Data Containers</title>
        <published>2023-06-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Rachid Ajaja</name><uri>https://github.com/abrajaja</uri>
	</author>
	
	<author>
		<name>Matthijs de Vries</name><uri>https://github.com/sudomati</uri>
	</author>
	
	<author>
		<name>Alexandros Athanasopulos</name><uri>https://github.com/Xaleee</uri>
	</author>
	
	<author>
		<name>Pavel Rubin</name><uri>https://github.com/pash7ka</uri>
	</author>
	
	<author>
		<name>Sebastian Galimberti Romano</name><uri>https://github.com/galimba</uri>
	</author>
	
	<author>
		<name>Daniel Berbesi</name><uri>https://github.com/berbex</uri>
	</author>
	
	<author>
		<name>Apostolos Mavropoulos</name><uri>https://github.com/ApostolosMavro</uri>
	</author>
	
	<author>
		<name>Barbara Marcano</name><uri>https://github.com/Barbara-Marcano</uri>
	</author>
	
	<author>
		<name>Daniel Ortega</name><uri>https://github.com/xdaniortega</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7208/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-7208-on-chain-data-container/14778" />
        

        <id>https://wg-eips.ritovision.com/7208/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7208"
            label="ERC-7208" />
        

        
        

        
        <summary type="html">Interoperability by abstracting logic away from storage</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7208/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC defines a series of interfaces for the abstraction of storage of on-chain data by implementing the logic functions that govern such data on independent smart contracts. &quot;On-chain Data Containers&quot; (ODCs) refer to the separation and indexing of data storage away from data management. We propose that on-chain data can be abstracted and stored in smart contracts called &quot;Data Objects&quot; (DO), which answer to external data indexing mechanisms named &quot;Data Points&quot; (DP). This data can be accessed and modified by implementing (one or many) separate smart contracts identified as &quot;Data Managers&quot; (DM). We introduce two mechanisms for access management: first, through a &quot;Data Index&quot; (DI) implementation, the &quot;Data Managers&quot; (DM) can be gated from accessing &quot;Data Objects&quot; (DO); second, a &quot;Data Point Registry&quot; (DPR) implementation manages the issuance of &quot;Data Points&quot; (DP). Lastly, we introduce the concept of data portability (horizontal data mobility) between implementations of &quot;Data Index&quot; (DI), enabling massive updates to the logic without affecting the underlying data storage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As the Ethereum ecosystem grows, so does the demand for on-chain functionalities. The market encourages a desire for broader adoption through more complex systems and there is a constant need for improved efficiency. We have seen times when an explosion of new standard token proposals was solely driven by market hype. While ultimately each standard serves its purpose, most of them require more flexibility to manage interoperability with other standards. A standard adapter mechanism is needed to enhance interoperability by driving the interactions between assets issued under different ERCs.&lt;&#x2F;p&gt;
&lt;p&gt;Without such mechanisms, most projects have implemented bespoke solutions for interoperability. This is an inefficient approach and leads to a fragmented ecosystem. We recognize there is no “one size fits all” solution to solve the standardization and interoperability challenges. Most assets - Fungible, Non-Fungible, Digital Twins, Real-world Assets, DePin, etc - have multiple mechanisms for representing them as on-chain tokens through the use of different standard interfaces and the diversity of standards spurs innovation.&lt;&#x2F;p&gt;
&lt;p&gt;However, for these assets to be exchanged, traded, or otherwise interacted with, protocols must implement compatibility with the relevant interfaces to access and modify on-chain data. This is especially challenging when considering the previously mentioned bespoke solutions for interoperability. Additionally, the immutability of smart contracts complicates the ability of already deployed protocols to adapt to new tokenization standards, which is critical for future-proofing implementations. A collaborative effort must be made to enable interaction between assets tokenized under different standards. The current ERC provides the tools for developing such on-chain adapters.&lt;&#x2F;p&gt;
&lt;p&gt;We aim to abstract the on-chain data handling from the logical implementation, exposing the underlying data independently of the ERC interface. We propose a series of interfaces for storing and accessing data on-chain in contracts called &quot;Data Objects&quot; (DO), grouping the underlying assets as generic &quot;Data Points&quot; (DP) that may be associated with multiple interoperable and even concurrent &quot;Data Manager&quot; (DM) contracts. This proposal is designed to work by coexisting with previous and future token standards, providing a flexible, efficient, and coherent mechanism to manage asset interoperability.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Abstraction&lt;&#x2F;strong&gt;: We propose a standardized interface for enabling developers to separate the data storage code from the underlying token utility logic, reducing the need for supporting and implementing multiple inherited -and often clashing- interfaces to achieve asset compatibility. The data (and therefore the assets) can be stored independently of the logic that governs such data.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Standard Neutrality&lt;&#x2F;strong&gt;: A neutral approach must enable the underlying data of any tokenized asset to transition seamlessly between different token standards. This will significantly improve interoperability among other standards, reducing fragmentation in the landscape. Our proposal aims to separate the storage of data representing an underlying asset from the standard interface used for representing the token.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consistent Interface&lt;&#x2F;strong&gt;: A uniform interface of primitive functions abstracts the data storage from the use case, irrespective of the underlying token&#x27;s standard or the interface exposing such data. Data and metadata can be stored on-chain, and exposed through the same primitives.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Portability&lt;&#x2F;strong&gt;: We provide a mechanism for the Horizontal Mobility of data between implementations of this standard, incentivizing the implementation of interoperable solutions and standard adapters.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;terms&quot;&gt;Terms&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Data Point&lt;&#x2F;strong&gt;: A uniquely identifiable reference to an on-chain data structure stored within one or many &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; and managed by one or many &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;. &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; are issued by a &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Object&lt;&#x2F;strong&gt;: A Smart Contract implementing the low-level storage management of information indexed through &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Manager&lt;&#x2F;strong&gt;: One or many Smart Contracts implementing the high-level logic and end-user interfaces for managing Data Objects.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;: One or many Smart Contracts used for managing the issuance of &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;. Additionally, a &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; defines a space of compatible or interoperable &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Index&lt;&#x2F;strong&gt;: One or many Smart Contracts used for managing the access of &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; to &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-point-structure&quot;&gt;Data Point Structure&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Data Point MUST be &lt;code&gt;bytes32&lt;&#x2F;code&gt; storage units.&lt;&#x2F;li&gt;
&lt;li&gt;Data Point SHOULD NOT be used for storing asset data.&lt;&#x2F;li&gt;
&lt;li&gt;Data Point SHOULD be used for indexing data.&lt;&#x2F;li&gt;
&lt;li&gt;Data Point SHOULD use a 4 bytes prefix for storing information relevant to the compatibility with other Data Points.&lt;&#x2F;li&gt;
&lt;li&gt;Data Point MUST use 4 bytes for storing the Chain ID&lt;&#x2F;li&gt;
&lt;li&gt;Data Point SHOULD use the last 20 bytes for identifying which Registry allocated them.&lt;&#x2F;li&gt;
&lt;li&gt;The RECOMMENDED internal structure of the Data Point is as follows:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * RECOMMENDED internal DataPoint structure on the Reference Implementation:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * 0xPPPPVVRRIIIIIIIIHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * - Prefix (bytes4)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- PPPP - Type prefix (i.e. 0x4450 - ASCII representation of letters &amp;quot;DP&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- VV   - Version of DataPoint specification (i.e. 0x00 for the reference implementation)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- RR   - Reserved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * - Registry-local identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- IIIIIIII - 32 bit implementation-specific id of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * - Chain ID (bytes4)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- HHHHHHHH - 32 bit of chain identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * - REGISTRY Address (bytes20)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * -- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Address of Registry which allocated the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Data Points&lt;&#x2F;strong&gt; are a low-level structure abstracting and indexing information. &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; act as pointers to information stored within data structures in &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;.
&lt;strong&gt;Data Points&lt;&#x2F;strong&gt; are allocated by a &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;. The &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; SHOULD store which &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; initialized it within its internal structure. Each &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; SHOULD have a unique identifier provided by the &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; when instantiated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-object-interface&quot;&gt;Data Object Interface&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Data Object SHOULD be used for storing asset data.&lt;&#x2F;li&gt;
&lt;li&gt;Data Object SHOULD use &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; for indexing the structure storing the data.&lt;&#x2F;li&gt;
&lt;li&gt;Data Object SHOULD implement the logic directly related to handling the data structure.&lt;&#x2F;li&gt;
&lt;li&gt;Data Object SHOULD implement the logic for transferring management of its &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; to a different &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; implementation.&lt;&#x2F;li&gt;
&lt;li&gt;Data Object MUST use the IDataObject interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDataObject&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reads stored data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read operation to run on the data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Operation-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; read&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Store data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Write operation to execute on the data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Operation-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-specific data (can be empty)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; write&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets DataIndex Implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newImpl&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the new DataIndex implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setDIImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newImpl&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; are entrusted with the storage and management of data. &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; SHOULD implement the logic for managing the storage of on-chain data. &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; internal data structure SHOULD use &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; for indexing information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; CAN receive &lt;code&gt;read()&lt;&#x2F;code&gt;, &lt;code&gt;write()&lt;&#x2F;code&gt;, or any other custom requests from a &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt; requesting access to a storage structure indexed by a &lt;strong&gt;Data Point&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As such, &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; respond to a gating mechanism given by a single &lt;strong&gt;Data Index&lt;&#x2F;strong&gt;. The function &lt;code&gt;setDIImplementation()&lt;&#x2F;code&gt; SHOULD enable the delegation of the management function to an &lt;code&gt;IDataIndex&lt;&#x2F;code&gt; implementation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-manager-contract&quot;&gt;Data Manager Contract&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Data Manager SHOULD use &lt;code&gt;IDataIndex.read()&lt;&#x2F;code&gt; or &lt;code&gt;IDataObject.read()&lt;&#x2F;code&gt; to read data from &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Manager MUST use &lt;code&gt;IDataIndex.write()&lt;&#x2F;code&gt; to write data to &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Manager MAY share &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; with other &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Manager MAY use multiple &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Manager SHOULD implement the logic for requesting &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; from a &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; are independent smart contracts that implement the business logic or &quot;high-level&quot; data management. They can &lt;code&gt;read()&lt;&#x2F;code&gt; from a &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; address and &lt;code&gt;write()&lt;&#x2F;code&gt; through a &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; implementation managing the delegated storage of the &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-point-registry-interface&quot;&gt;Data Point Registry Interface&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Data Point Registry SHOULD define functions to manage the creation, transfer, and access control of &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Point Registry SHOULD manage &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; access management for &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Data Point Registry MUST use the IDataPointRegistry interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDataPointRegistry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies if an address has an Admin role for a DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Account to verify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allocates a DataPoint to an owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner of the new DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner should be granted Admin role during allocation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allocate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;DataPoint&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers a DataPoint to an owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Data Point to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner of the new DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferOwnership&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newOwner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Grant permission to grant&#x2F;revoke other roles on the DataPoint inside a Data Index Implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This is useful if DataManagers are deployed during lifecycle of the application.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; If&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the role was granted (otherwise account already had the role)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; grantAdminRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Revoke permission to grant&#x2F;revoke other roles on the DataPoint inside a Data Index Implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Old admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If an owner revokes Admin role from himself, he can add it again&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; If&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the role was revoked (otherwise account didn&amp;#39;t have the role)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeAdminRole&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; is a smart contract entrusted with &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; access control. &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; may request the allocation of &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; to the &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-index-interface&quot;&gt;Data Index Interface&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;DataIndex SHOULD manage the access of &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; to &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;DataIndex SHOULD manage internal IDs for each user.&lt;&#x2F;li&gt;
&lt;li&gt;DataIndex MUST use the IDataIndex interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDataIndex&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies if DataManager is allowed to write specific DataPoint on specific DataObject&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dm&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of DataManager&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; write access is allowed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedDataManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dm&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Defines if DataManager is allowed to write specific DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dm&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of DataManager&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if DataManager should be approved for the DataPoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function should be restricted to DataPoint maintainer only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowDataManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dm&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reads stored data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dobj&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of DataObject&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the datapoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read operation to execute on the data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Operation-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; read&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dobj&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Store data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dobj&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of DataObject&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier of the datapoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read operation to execute on the data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Operation-specific data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Operation&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-specific data (can be empty)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function should be restricted to allowed DMs only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; write&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dobj&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; dp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; is a smart contract entrusted with access control. It is a gating mechanism for &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; to access &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;. If a &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt; intends to access a &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; (either by &lt;code&gt;read()&lt;&#x2F;code&gt;, &lt;code&gt;write()&lt;&#x2F;code&gt;, or any other method), the &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; SHOULD be used for validating access to the data.&lt;&#x2F;p&gt;
&lt;p&gt;The mechanism for ID management determines a space of compatibility between implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The decision to encode &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; as &lt;code&gt;bytes32&lt;&#x2F;code&gt; data pointers is primarily driven by flexibility and future-proofing. The use &lt;code&gt;bytes32&lt;&#x2F;code&gt; allows for a wide range of data encodings. This provides the developer with many options to accommodate diverse use cases. Furthermore, as Ethereum and its standards continue to evolve, encoding as &lt;code&gt;bytes32&lt;&#x2F;code&gt; ensures that the Standard Adapters built with the current ERC can reference future data types or structures without requiring significant changes to the adapter itself. The &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; encoding should have a prefix so that the &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; can efficiently identify compatibility issues when accessing the data storage. Additionally, the prefix should be used to find the &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; and verify admin access to the &lt;strong&gt;Data Point&lt;&#x2F;strong&gt;. The use of a suffix for identifying the &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; is also required, for the &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; to quickly discard badly formed transactions that aim to use a &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; from an unmatching &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Manager&lt;&#x2F;strong&gt; implementations decide which &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; they will be using. Their allocation is managed through a &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt;, and the &lt;code&gt;write()&lt;&#x2F;code&gt; access to the &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; is managed by passing through the &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; implementation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; are independent separate Smart Contracts that implement the same &lt;code&gt;read&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;write&lt;&#x2F;code&gt; interface for communicating with &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;. This is a decision mainly driven by the scalability of the system. Offering a simple interface for this layered structure enables different applications to have their addresses for storage of data independently from the asset&#x27;s interface. It is up to each implementation to manage access to their &lt;strong&gt;Data Point&lt;&#x2F;strong&gt; storage space. This enables a wide array of complex, dynamic, and interactive use cases to be implemented with multiple ERCs as well as other smart contracts, including the embedding of cross-chain and rollup logic for asset management.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; offer flexibility in storing mutable on-chain data that can be modified as per the requirements of each specific use case. This enables the &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; to hold mutable states in delegated storage and reflect changes over time, providing a dynamic layer to the otherwise static nature of storage through most other standardized interfaces.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; can decide to migrate the complete storage management of a &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; from one &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; implementation to another. As the &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; implements user ID management, this mechanism enables a &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt; to upgrade its internal access control mechanisms without affecting the underlying storage of value, as it is located elsewere (in the &lt;strong&gt;Data Object&lt;&#x2F;strong&gt;). We call this mechanism &quot;Horizontal Data Mobility&#x2F;Portability&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC is intended to augment the functionality of existing token standards without introducing breaking changes. As such, it does not present any backward compatibility issues. Already deployed tokens under other ERCs can be wrapped and indexed as &lt;strong&gt;Data Points&lt;&#x2F;strong&gt; and managed by &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt;, and later exposed through any implementation of &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;. All interoperability integrations will require a compatibility analysis, depending on the use case. However, the interfaces defined in this ERC define a framework for adapting one standard to another through storage abstraction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;We present an &lt;em&gt;educational example&lt;&#x2F;em&gt; implementation of a Standard Adapter showcasing two types of tokens (Fungible and Semi-Fungible) with shared data storage. The end user can interact with this implementation through one of two types of interfaces: The semi-fungible one (represented through a single &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt;), and the fungible interface (represented by many &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt;). The abstraction of the storage from the logic is achieved through the use of a single &lt;em&gt;Fungible Fractions&lt;&#x2F;em&gt; &lt;strong&gt;Data Object&lt;&#x2F;strong&gt;. A factory is used for deploying the Fungible token interfaces that share storage with each semi-fungible collection. Note that if a &lt;code&gt;transfer()&lt;&#x2F;code&gt; is called by either interface (Fungible or Semi-Fungible), both interfaces are emitting an event.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;This example has not been audited and should not be used in production environments.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7208&#x2F;assets&#x2F;contracts&#x2F;README&#x2F;&quot;&gt;contracts&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The access control is separated into three layers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Layer 1&lt;&#x2F;strong&gt;: The &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; allocates for &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; and manages ownership (admin&#x2F;write rights) of &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Layer 2&lt;&#x2F;strong&gt;: The &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; smart contract implements Access Control by managing Approvals of &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; to &lt;strong&gt;Data Points&lt;&#x2F;strong&gt;. It uses the &lt;strong&gt;Data Point Registry&lt;&#x2F;strong&gt; to verify who can grant&#x2F;revoke this access.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Layer 3&lt;&#x2F;strong&gt;: The &lt;strong&gt;DataObject&lt;&#x2F;strong&gt; manages trust relationship between the &lt;strong&gt;DataPoint&lt;&#x2F;strong&gt; and a &lt;strong&gt;DataIndex&lt;&#x2F;strong&gt;  implementation and allows a trusted &lt;strong&gt;DataIndex&lt;&#x2F;strong&gt; to execute &lt;code&gt;write&lt;&#x2F;code&gt; operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A common task for a &lt;strong&gt;Data Object&lt;&#x2F;strong&gt; is to store user-related data, while the &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt; implements the logic for managing such data. Both &lt;strong&gt;Data Objects&lt;&#x2F;strong&gt; and &lt;strong&gt;Data Managers&lt;&#x2F;strong&gt; often require the management of user IDs. A &lt;strong&gt;Data Index&lt;&#x2F;strong&gt; can offer logic for user management (i.e. IDs based on &lt;code&gt;address&lt;&#x2F;code&gt;) that are independent of any particular implementation, but care must be taken in selecting these identifiers. If chosen improperly, they could hinder a &lt;strong&gt;Data Manager&lt;&#x2F;strong&gt;&#x27;s ability to migrate between different &lt;strong&gt;Data Indexes&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;No further security considerations are derived specifically from this ERC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Financial Bonds</title>
        <published>2023-05-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Samuel Gwlanold Edoumou</name><uri>https://github.com/Edoumou</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7092/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/financial-bonds/14461" />
        

        <id>https://wg-eips.ritovision.com/7092/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7092"
            label="ERC-7092" />
        

        
        

        
        <summary type="html">Represents debt issued by entities to investors.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7092/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces fixed-income financial bonds with key characteristics defined to facilitate bond issuance in the primary market and enable buying or selling bonds in the secondary market. The standard also provides cross-chain functionalities for bonds operations and management across multiple blockchains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Fixed-income instruments are a widely utilized asset class for corporations and other entities raising funds. However, transitioning to tokenized bonds is challenging due to existing standards like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;&quot;&gt;ERC-3475&lt;&#x2F;a&gt;, which introduces unfamiliar concepts and leads to unnecessary gas consumption. Additionally, the lack of named variables like coupon, maturity date, and principal, makes it difficult to implement ERC-3475 since developers need to remember which metadata is assigned to each parameter.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Every contract compliant with this ERC MUST implement the following Token Interface as well as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-7092 Financial Bonds Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7092&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account that owns bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account that receives the bond&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when an account is approved or when the allowance is decreased&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bond token&amp;#39;s owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account to be allowed to spend bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens allowed by _owner to be spent by `_spender`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *        Or amount of bond tokens to decrease allowance from `_spender`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when multiple bond tokens are transferred, issued or redeemed, with the exception being during contract creation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of bondholders accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to transfer bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchTransfer` and `batchTransferFrom` functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when multiple accounts are approved or when the allowance is decreased from multiple accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bondholder account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be allowed to spend bonds, or to decrase the allowance from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens allowed by `_owner` to be spent by multiple accounts in `_spender`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchApprove` and `batchDecreaseAllowance` functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getter functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond isin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond symbol&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer&amp;#39;shorter name and the maturity date&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond currency. This is the contract address of the token used to pay and return the bond principal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; currency&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unit of the principal currency&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         ex: If the denomination is equal to 1,000 and the currency is USDC, then the bond denomination is equal to 1,000 USDC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; denomination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in denomination unit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; issueVolume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         1 basis point = 0.01% = 0.0001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         ex: if interest rate = 5%, then coupon() =&amp;gt; 500 basis points&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; couponRate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; issueDate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the bond maturity date, i.e, the date when the principal is repaid. This is a Unix Timestamp like the one returned by block.timestamp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         The maturity date MUST be greater than the issue date&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; maturityDate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; account address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; principalOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the amount of tokens the `_spender` account has been authorized by the `_owner``&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         account to manage their bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the bondholder address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address that has been authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; setter functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizes `_spender` account to manage `_amount`of their bond tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Lowers the allowance of `_spender` by `_amount`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to remove from allowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decreaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address to send the bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Moves `_amount` bonds from an account that has authorized the caller through the approve function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the bondholder address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address to transfer bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; batch functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizes multiple spender accounts to manage a specified `_amount` of the bondholder tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchApprove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Decreases the allowance of multiple spenders by corresponding amounts in `_amount`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to decrease the allowance from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease token allowance.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchDecreaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers multiple bonds with amounts specified in the array `_amount` to the corresponding accounts in the array `_to`, with the option to attach additional data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to send the bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers multiple bonds with amounts specified in the array `_amount` to the corresponding accounts in the array `_to` from an account that have been authorized by the `_from` account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This method also allows to attach data to tokens that are being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of bondholder accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to transfer bond tokens to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;additional-bond-parameters-interface&quot;&gt;Additional bond parameters Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;IERC7092ESG&lt;&#x2F;code&gt; interface is OPTIONAL for contracts implementing this proposal. This interface MAY be used to improve the standard usability.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;currencyOfCoupon&lt;&#x2F;code&gt; The currency used for coupon payment may be different from the currency used to repay the principal&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;couponType&lt;&#x2F;code&gt; MAY be employed to signify the interest rate that the issuer has committed to paying to investors, which may take various forms such as zero coupon, fixed rate, floating rate, and more.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;couponFrequency&lt;&#x2F;code&gt; refers to how often the bond pays interest to its bondholders, and is typically expressed in terms of time periods, such as: Annual, Semi-Annual, Quarterly, or Monthly.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;dayCountBasis&lt;&#x2F;code&gt; is used to calculate the accrued interest on a bond between two coupon payment dates or other specific periods. Some of the day count basis are: Actual&#x2F;Actual, 30&#x2F;360, Actual&#x2F;360, Actual&#x2F;365, or 30&#x2F;365&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7092ESG&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the number of decimals used by the bond. For example, if it returns `10`, it means that the token amount MUST be multiplied by 10000000000 to get the standard representation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decimals&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rreturns the coupon currency, which is represented by the contract address of the token used to pay coupons. It can be the same as the one used for the principal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; currencyOfCoupon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the coupon type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         For example, 0 can denote Zero coupon, 1 can denote Fixed Rate, 2 can denote Floating Rate, and so on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; couponType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the coupon frequency, i.e. the number of times coupons are paid in a year.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; couponFrequency&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the day count basis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         For example, 0 can denote actual&#x2F;actual, 1 can denote actual&#x2F;360, and so on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; dayCountBasis&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;cross-chain-interface&quot;&gt;Cross-chain Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The standard permits the implementation of the &lt;code&gt;IERC7092CrossChain&lt;&#x2F;code&gt; interface for cross-chain management of bond tokens. This interface is OPTIONAL and may be used by applications to allow cross-chain transactions. Any function initiating a cross-chain transaction MUST explicitly define the destination chain identifier &lt;code&gt;destinationChainID&lt;&#x2F;code&gt; and specify the target smart contract &lt;code&gt;destinationContract&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7092CrossChain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when bond tokens are transferred or redeemed in a cross-chain transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bondholder account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; account the transfer bond tokens to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CrossChainTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when several bond tokens are transferred or redeemed in a cross-chain transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of bondholders accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts that receive the bond&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amount of bond tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identify the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CrossChainTransferBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when an account is approved to spend the bondholder&amp;#39;s tokens in a different chain than the current chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the bondholder account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account to be allowed to spend bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens allowed by `_owner` to be spent by `_spender`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CrossChainApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when multiple accounts in the array `_spender` are approved or when the allowances of multiple accounts in the array `_spender` are reduced on the destination chain which MUST be different than the current chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bond token&amp;#39;s owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be allowed to spend bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amount of bond tokens allowed by _owner to be spent by _spender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identify the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CrossChainApprovalBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizes the `_spender` account to manage a specified `_amount`of the bondholder bond tokens on the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; account to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The smart contract to interact with in the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainApprove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizes multiple spender accounts in `_spender` to manage specified amounts in `_amount` of the bondholder tokens on the destination chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainBatchApprove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Decreases the allowance of `_spender` by a specified `_amount` on the destination Chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to remove from allowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainDecreaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Decreases the allowance of multiple spenders in `_spender` by corresponding amounts specified in the array `_amount` on the destination chain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to be authorized by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to decrease the allowance from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainBatchDecreaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Moves `_amount` bond tokens to the address `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; account to send bond tokens to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; additional information provided by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The smart contract to interact with in the destination Chain in order to Deposit or Mint bond tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers multiple bond tokens with amounts specified in the array `_amount` to the corresponding accounts in the array `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to send the bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of additional information provided by the bondholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identify the destination Chains.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of smart contracts to interact with in the destination Chains in order to Deposit or Mint bond tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainBatchTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers `_amount` bond tokens from the `_from`account to the `_to` account from the current chain to another chain. The caller must be approved by the `_from` address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the bondholder address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account to transfer bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; amount of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique ID that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers several bond tokens with amounts specified in the array `_amount` from accounts in the array `_from` to accounts in the array `_to` from the current chain to another chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         The caller must be approved by the `_from` accounts to spend the corresponding amounts specified in the array `_amount`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         This methods also allows to attach data to the token that is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of bondholder addresses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of accounts to transfer bonds to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of amounts of bond tokens to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of additional information provided by the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of unique IDs that identifies the destination Chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; crossChainBatchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationChainID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _destinationContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The design of this ERC aims to simplify the migration to tokenized bonds by maintaining consistency with traditional bond standards. This approach allows fixed-income instruments to be represented as on-chain tokens, manageable through wallets, and utilized by applications like decentralized exchanges, while avoiding the complexities and inefficiencies associated with other standards. This ERC facilitates the creation of new bond tokens with characteristics akin to traditional bonds, enhancing accessibility, liquidity, and cost-efficiency in bond trading and management.&lt;&#x2F;p&gt;
&lt;p&gt;The use of traditional finance terminology, like &lt;code&gt;issueVolume&lt;&#x2F;code&gt; and &lt;code&gt;principalOf&lt;&#x2F;code&gt;, is aimed at maintaining consistency with traditional bond language, which eases the adaptation for traditional entities.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;total-supply-and-account-balance&quot;&gt;Total Supply and Account Balance&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;totalSupply&lt;&#x2F;code&gt; and &lt;code&gt;balanceOf&lt;&#x2F;code&gt; functions are not defined as they can be derived from &lt;code&gt;issueVolume&lt;&#x2F;code&gt; and &lt;code&gt;principalOf&lt;&#x2F;code&gt;, and &lt;code&gt;denomination&lt;&#x2F;code&gt;. However, these functions can be be added in any contract implementing this standard, ensuring the proper relationship between these values.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; issueVolume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; denomination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balance0f&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; principal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; denomination&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC is not backwards compatible with existing standards like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; due to the absence of certain functions like &lt;code&gt;totalSupply&lt;&#x2F;code&gt; or &lt;code&gt;balanceOf&lt;&#x2F;code&gt;. A pure implementation of this standard is RECOMMENDED for issuing tokenized bonds, as any hybrid solution with other mentioned standards SHOULD fail.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The complete Reference Implementation can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7092&#x2F;.&#x2F;assets&#x2F;ERC7092.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Bonds with embedded options like callable, puttable, or convertible bonds can be created by inheriting from the reference &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7092&#x2F;.&#x2F;assets&#x2F;ERC7092.sol&quot;&gt;&lt;code&gt;ERC7092.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; that integrates the proposed interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;callable-bonds&quot;&gt;CALLABLE BONDS:&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;ERC7092.sol&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092Callable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WRITE THE LOGIC TO ALLOW THE ISSUER TO CALL BONDS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; STATE VARIABLES AND FUNCTIONS NEEDED&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; call bonds owned by `_investor`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         MUST be called by the issuer only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _investor&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _issuer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bondISIN&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;issuerAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Callable: ONLY_ISSUER&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_investor&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Callable: NO_BONDS&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _bond&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bondISIN&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;maturityDate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Callable: BOND_MATURED&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; principal &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;  _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_investor&lt;&#x2F;span&gt;&lt;span&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&gt;        _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_investor&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ADD LOGIC HERE&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;h3 id=&quot;puttable-bonds&quot;&gt;PUTTABLE BONDS:&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;ERC7092.sol&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092Puttable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WRITE THE LOGIC TO ALLOW INVESTORS TO PUT BONDS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; STATE VARIABLES AND FUNCTIONS NEEDED&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; put bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         MUST be called by investors who own bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; put&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Puttable: ONLY_INVESTORS&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _bond&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bondISIN&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;maturityDate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Puttable: BOND_MATURED&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; principal &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;  _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&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&gt;        _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ADD LOGIC&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;h3 id=&quot;convertible-bonds&quot;&gt;CONVERTIBLE BONDS:&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;ERC7092.sol&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092Convertible&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC7092&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WRITE THE LOGIC TO ALLOW INVESTOR OR ISSUER TO CONVERT BONDS TO EQUITY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; STATE VARIABLES AND FUNCTIONS NEEDED&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; convert bonds to equity. Here we assumed that the investors must convert their bonds to equity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *         Issuer can also convert invetsors bonds to equity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Convertible: ONLY_INVESTORS&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _bond&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;bondISIN&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;maturityDate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC7092Convertible: BOND_MATURED&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; principal &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;  _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&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&gt;        _principals&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ADD LOGIC HERE&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;h3 id=&quot;identity-registry&quot;&gt;Identity Registry&lt;&#x2F;h3&gt;
&lt;p&gt;This standard is designed specifically for tokenizing bonds. It does not inherently manage information pertaining to bondholders&#x27; identities. However, to enhance compliance with regulatory requirements and improve transparency, an identity registry can be added  on top of this standard to store the identity of all authorized investors.&lt;&#x2F;p&gt;
&lt;p&gt;By maintaining an identity registry, issuers can ensure that bond tokens issued under the &lt;code&gt;ERC7092&lt;&#x2F;code&gt; standard are transferred only to registered and authorized entities. This practice aligns with regulatory compliance measures and provides a structured way to manage and verify the identity of bondholders. It also helps prevent unauthorized or non-compliant transfers of bond tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Implementing this ERC requires careful consideration of security risks related to functions approving operators to manage owner&#x27;s bonds and functions allowing bond transfers. The use of these functions necessitates robust validation to ensure only the bond owner or approved accounts can call them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC-1155 Supply Extension</title>
        <published>2023-05-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5615/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5615-eip-1155-supply-extension/10732" />
        

        <id>https://wg-eips.ritovision.com/5615/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5615"
            label="ERC-5615" />
        

        
        

        
        <summary type="html">A simple mechanism to fetch token supply data from ERC-1155 tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5615/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC standardizes an existing mechanism to fetch token supply data from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; tokens. It adds a &lt;code&gt;totalSupply&lt;&#x2F;code&gt; function, which fetches the number of tokens with a given &lt;code&gt;id&lt;&#x2F;code&gt;, and an &lt;code&gt;exists&lt;&#x2F;code&gt; function, which checks for the existence of a given &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155Supply&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice      This function MUST return whether the given token id exists, previously existed, or may exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param   id  The token id of which to check the existence&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @return      Whether the given token id exists, previously existed, or may exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice      This function MUST return the number of tokens with a given id. If the token id does not exist, it MUST return 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @param   id  The token id of which fetch the total supply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @return      The total supply of the given token id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Implementations MAY support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface discovery, but consumers MUST NOT rely on it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC does not implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, as this interface is simple enough that the extra complexity is unnecessary and would cause incompatibilities with pre-existing implementations.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;totalSupply&lt;&#x2F;code&gt; and &lt;code&gt;exists&lt;&#x2F;code&gt; functions were modeled after &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;totalSupply&lt;&#x2F;code&gt; does not revert if the token ID does not exist, since contracts that care about that case should use &lt;code&gt;exists&lt;&#x2F;code&gt; instead (which might return false even if &lt;code&gt;totalSupply&lt;&#x2F;code&gt; is zero).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;exists&lt;&#x2F;code&gt; is included to differentiate between the two ways that &lt;code&gt;totalSupply&lt;&#x2F;code&gt; could equal zero (either no tokens with the given ID have been minted yet, or no tokens with the given ID will ever be minted).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC is designed to be backward compatible with the OpenZeppelin &lt;code&gt;ERC1155Supply&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Lockable Extension for ERC-721</title>
        <published>2023-05-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Piyush Chittara</name><uri>https://github.com/piyush-chittara</uri>
	</author>
	
	<author>
		<name>StreamNFT</name><uri>https://github.com/streamnft-tech</uri>
	</author>
	
	<author>
		<name>Srinivas Joshi</name><uri>https://github.com/SrinivasJoshi</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7066/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7066-lockable-extension-for-erc721/14425" />
        

        <id>https://wg-eips.ritovision.com/7066/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7066"
            label="ERC-7066" />
        

        
        

        
        <summary type="html">Interface for enabling locking of ERC-721 using locker and approved</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7066/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;An extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, this standard incorporates &lt;code&gt;locking&lt;&#x2F;code&gt; features into NFTs, allowing for various uses while preventing sale or transfer. The token&#x27;s &lt;code&gt;owner&lt;&#x2F;code&gt; can &lt;code&gt;lock&lt;&#x2F;code&gt; it, setting up locker address (either an EOA or a contract) that exclusively holds the power to unlock the token. Owner can also provide approval for &lt;code&gt;tokenId&lt;&#x2F;code&gt;, enabling ability to lock asset while address holds the token approval. Token can also be locked by &lt;code&gt;approved&lt;&#x2F;code&gt;, assigning locker to itself. Upon token transfer, these rights get purged.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; has sparked an unprecedented surge in demand for NFTs. However, despite this tremendous success, the NFT economy suffers from secondary liquidity where it remains illiquid in owner’s wallet. There are projects which aim to address the liquidity challenge, but they entail the below mentioned inconveniences and risks for owners as they necessitate transferring the participating NFTs to the projects&#x27; contracts.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Loss of utility: The utility value of NFTs diminishes when they are transferred to an escrow account, no longer remaining under the direct custody of the owners.&lt;&#x2F;li&gt;
&lt;li&gt;Lack of composability: The market could benefit from increased liquidity if NFT owners had access to multiple financial tools, such as leveraging loans and renting out their assets for maximum returns. Composability serves as the missing piece in creating a more efficient market.&lt;&#x2F;li&gt;
&lt;li&gt;Smart contract vulnerabilities: NFTs are susceptible to loss or theft due to potential bugs or vulnerabilities present in the smart contracts they rely on.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The aforementioned issues contribute to a poor user experience (UX), and we propose enhancing the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard by implementing a native locking mechanism:
Rather than being transferred to a smart contract, an NFT remains securely stored in self-custody but is locked.
During the lock period, the NFT&#x27;s transfer is restricted while its other properties remain unchanged.
NFT Owner retains the ability to use or distribute it’s utility.&lt;&#x2F;p&gt;
&lt;p&gt;NFTs have numerous use cases where the NFT must remain within the owner&#x27;s wallet, even when it serves as collateral for a loan. Whether it&#x27;s authorizing access to a Discord server, or utilizing NFT within a play-to-earn (P2E) game, owner should have the freedom to do so throughout the lending period. Just as real estate owner can continue living in their mortgaged house, take personal loan or keep tenants to generate passive income, these functionalities should be available to NFT owners to bring more investors in NFT economy.&lt;&#x2F;p&gt;
&lt;p&gt;Lockable NFTs enable the following use cases :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;NFT-collateralized loans: Utilize NFT as collateral for a loan without locking it on the lending protocol contract. Instead, lock it within owner’s wallet while still enjoying all the utility of NFT.&lt;&#x2F;li&gt;
&lt;li&gt;No collateral rentals of NFTs: Borrow an NFT for a fee without the need for significant collateral. Renter can use the NFT but not transfer it, ensuring the lender&#x27;s safety. The borrowing service contract automatically returns the NFT to the lender once the borrowing period expires.&lt;&#x2F;li&gt;
&lt;li&gt;Buy Now Pay Later (BNPL): The buyer receives the locked NFT and can immediately begin using it. However, they are unable to sell the NFT until all installments are paid. Failure to complete the full payment results in the NFT returning to the seller, along with a fee.&lt;&#x2F;li&gt;
&lt;li&gt;Composability: Maximize liquidity by having access to multiple financial tools. Imagine taking a loan against NFT and putting it on rentals to generate passive income.&lt;&#x2F;li&gt;
&lt;li&gt;Primary sales: Mint an NFT for a partial payment and settle the remaining amount once owner is satisfied with the collection&#x27;s progress.&lt;&#x2F;li&gt;
&lt;li&gt;Soulbound: Organization can mint and self-assign &lt;code&gt;locker&lt;&#x2F;code&gt;, send token to user and lock the asset.&lt;&#x2F;li&gt;
&lt;li&gt;Safety: Safely and conveniently use exclusive blue chip NFTs. Lockable extension allows owner to lock NFT and designate secure cold wallet as the unlocker. This way, owner can keep NFT on MetaMask and easily use it, even if a hacker gains access to MetaMask account. Without access to the cold wallet, the hacker cannot transfer NFT, ensuring its safety.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal is different from other locking proposals in number of ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This implementation provides a minimal implementation of &lt;code&gt;lock&lt;&#x2F;code&gt; and &lt;code&gt;unlock&lt;&#x2F;code&gt; and believes other conditions like time-bound are great ideas but can be achieved without creating a specific implementation. Locking and Unlocking can be based on any conditions (e.g. repayment, expiry). Therefore time-bound unlocks a relatively specific use case that can be achieved via smart-contracts themselves without that being a part of the token contract.&lt;&#x2F;li&gt;
&lt;li&gt;This implementation proposes a separation of rights between locker and approver. Token can be locked with approval and approved can unlock and withdraw tokens (opening up opportunities like renting, lending, BNPL etc), and token can be locked lacking the rights to revoke token, yet can unlock if required (opening up opportunities like account-bound NFTs).&lt;&#x2F;li&gt;
&lt;li&gt;Our proposal implement ability to &lt;code&gt;transferAndLock&lt;&#x2F;code&gt; which can be used to transfer, lock and optionally approve token. Enabling the possibility of revocation after transfer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;By extending the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard, the proposed standard enables secure and convenient management of underlying NFT assets. It natively supports prevalent NFTFi use cases such as staking, lending, and renting. We anticipate that this proposed standard will foster increased engagement of NFT owners in NFTFi projects, thereby enhancing the overall vitality of the NFT ecosystem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; compliant contracts MAY implement this EIP to provide standard methods of locking and unlocking the token at its current owner address.&lt;&#x2F;p&gt;
&lt;p&gt;Token owner MAY &lt;code&gt;lock&lt;&#x2F;code&gt; the token and assign &lt;code&gt;locker&lt;&#x2F;code&gt; to some &lt;code&gt;address&lt;&#x2F;code&gt; using &lt;code&gt;lock(uint256 tokenId, address _locker)&lt;&#x2F;code&gt; function, this MUST set &lt;code&gt;locker&lt;&#x2F;code&gt; to &lt;code&gt;_locker&lt;&#x2F;code&gt;. Token owner or approved MAY &lt;code&gt;lock&lt;&#x2F;code&gt; the token using &lt;code&gt;lock(uint256 tokenId)&lt;&#x2F;code&gt; function, this MUST set &lt;code&gt;locker&lt;&#x2F;code&gt; to &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. Token MAY be &lt;code&gt;unlocked&lt;&#x2F;code&gt; by &lt;code&gt;locker&lt;&#x2F;code&gt; using &lt;code&gt;unlock&lt;&#x2F;code&gt; function. &lt;code&gt;unlock&lt;&#x2F;code&gt; function MUST delete &lt;code&gt;locker&lt;&#x2F;code&gt; mapping and default to &lt;code&gt;address(0)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the token is &lt;code&gt;locked&lt;&#x2F;code&gt;, the &lt;code&gt;lockerOf&lt;&#x2F;code&gt; function MUST return an address that is &lt;code&gt;locker&lt;&#x2F;code&gt; and can &lt;code&gt;unlock&lt;&#x2F;code&gt; the token. For tokens that are not &lt;code&gt;locked&lt;&#x2F;code&gt;, the &lt;code&gt;lockerOf&lt;&#x2F;code&gt; function MUST return &lt;code&gt;address(0)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;lock&lt;&#x2F;code&gt; function MUST revert if token is already &lt;code&gt;locked&lt;&#x2F;code&gt;. &lt;code&gt;unlock&lt;&#x2F;code&gt; function MUST revert if token is not &lt;code&gt;locked&lt;&#x2F;code&gt;. ERC-721 &lt;code&gt;approve&lt;&#x2F;code&gt; function MUST revert if token is &lt;code&gt;locked&lt;&#x2F;code&gt;. ERC-721 functions that transfer ownership of a token MUST revert if token is &lt;code&gt;locked&lt;&#x2F;code&gt;, unless &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is &lt;code&gt;approved&lt;&#x2F;code&gt; and &lt;code&gt;locker&lt;&#x2F;code&gt; both. After ERC-721 token transfer function call, values of &lt;code&gt;locker&lt;&#x2F;code&gt; and &lt;code&gt;approved&lt;&#x2F;code&gt; MUST be purged.&lt;&#x2F;p&gt;
&lt;p&gt;Token MAY be transferred and &lt;code&gt;locked&lt;&#x2F;code&gt;, also assign &lt;code&gt;approval&lt;&#x2F;code&gt; to &lt;code&gt;locker&lt;&#x2F;code&gt; using &lt;code&gt;transferAndLock&lt;&#x2F;code&gt; function. This is RECOMMENDED for use-cases where Token transfer and subsequent revocation is REQUIRED.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; SPDX-License-Identifier: CC0-1.0&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;pragma solidity &amp;gt;=0.7.0 &amp;lt;0.9.0;&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;&#x2F; @title Lockable Extension for ERC721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Interface for the Lockable extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @author StreamNFT &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;interface IERC7066{&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Emitted when tokenId is locked&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;    event Lock (uint256 indexed tokenId, address _locker);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Emitted when tokenId is unlocked&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;    event Unlock (uint256 indexed tokenId);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Lock the tokenId if msg.sender is owner or approved and set locker to msg.sender&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;    function lock(uint256 tokenId) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Lock the tokenId if msg.sender is owner and set locker to _locker&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;    function lock(uint256 tokenId, address _locker) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Unlocks the tokenId if msg.sender is locker&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;    function unlock(uint256 tokenId) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Tranfer and lock the token if the msg.sender is owner or approved. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      Lock the token and set locker to caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      Optionally approve caller if bool setApprove flag is true&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;    function transferAndLock(uint256 tokenId, address from, address to, bool setApprove) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Returns the wallet, that is stated as unlocking wallet for the tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      If address(0) returned, that means token is not locked. Any other result means token is locked.&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;    function lockerOf(uint256 tokenId) external view returns (address);&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal set &lt;code&gt;locker[tokenId]&lt;&#x2F;code&gt; to &lt;code&gt;address(0)&lt;&#x2F;code&gt; when token is &lt;code&gt;unlocked&lt;&#x2F;code&gt; because we delete mapping on &lt;code&gt;locker[tokenId]&lt;&#x2F;code&gt; freeing up space. Also, this assertion helps our contract to validate if token is &lt;code&gt;locked&lt;&#x2F;code&gt; or &lt;code&gt;unlocked&lt;&#x2F;code&gt; for internal function calls.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal exposes &lt;code&gt;transferAndLock(uint256 tokenId, address from, address to, bool setApprove)&lt;&#x2F;code&gt; which can be used to transfer token and lock at the receiver&#x27;s address. This additionally accepts input &lt;code&gt;bool setApprove&lt;&#x2F;code&gt; which on &lt;code&gt;true&lt;&#x2F;code&gt; assign &lt;code&gt;approval&lt;&#x2F;code&gt; to &lt;code&gt;locker&lt;&#x2F;code&gt;, hence enabling &lt;code&gt;locker&lt;&#x2F;code&gt; to revoke the token (revocation conditions can be defined in contracts and &lt;code&gt;approval&lt;&#x2F;code&gt; provided to contract). This provides conditional ownership to receiver, without the privilege to &lt;code&gt;transfer&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standards.&lt;&#x2F;p&gt;
&lt;p&gt;Existing Upgradedable &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; can upgrade to this standard, enabling locking capability inherently and unlock underlying liquidity features.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7066&#x2F;.&#x2F;assets&#x2F;test&#x2F;test.js&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Reference Interface can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7066&#x2F;.&#x2F;assets&#x2F;IERC7066.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Reference Implementation can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7066&#x2F;.&#x2F;assets&#x2F;ERC7066.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard for the contract that manages &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;considerations-for-the-contracts-that-work-with-lockable-tokens&quot;&gt;Considerations for the contracts that work with lockable tokens&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Once &lt;code&gt;locked&lt;&#x2F;code&gt;, token can not be further &lt;code&gt;approved&lt;&#x2F;code&gt; or &lt;code&gt;transfered&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If token is &lt;code&gt;locked&lt;&#x2F;code&gt; and caller is &lt;code&gt;locker&lt;&#x2F;code&gt; and &lt;code&gt;approved&lt;&#x2F;code&gt; both, caller can transfer the token.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;locked&lt;&#x2F;code&gt; token with &lt;code&gt;locker&lt;&#x2F;code&gt; as in-accesible account or un-verified contract address can lead to permanent lock of the token.&lt;&#x2F;li&gt;
&lt;li&gt;There are no MEV considerations regarding lockable tokens as only authorized parties are allowed to lock and unlock.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Interoperable Digital Media Indexing</title>
        <published>2023-05-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bofu Chen</name><uri>https://github.com/bafu</uri>
	</author>
	
	<author>
		<name>Tammy Yang</name><uri>https://github.com/tammyyang</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7053/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7053-interoperable-digital-media-indexing/14394" />
        

        <id>https://wg-eips.ritovision.com/7053/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:7053"
            label="ERC-7053" />
        

        
        

        
        <summary type="html">A universal indexing method to record, discover and retrieve the history of digital media on EVM-compatible blockchains.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7053/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes an interoperable indexing strategy designed to enhance the organization and retrieval of digital media information across multiple smart contracts and EVM-compatible blockchains. This system enhances the traceability and verification of cross-contract and cross-chain data, facilitating a more efficient discovery of storage locations and crucial information related to media assets. The major purpose is to foster an integrated digital media environment on the blockchain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Given the significant role digital media files play on the Internet, it&#x27;s crucial to have a robust and efficient method for indexing immutable information. Existing systems encounter challenges due to the absence of a universal, interoperable identifier for digital media content. This leads to fragmentation and complications in retrieving metadata, storage information, or the provenance of specific media assets. The issues become increasingly critical as the volume of digital media continues to expand.&lt;&#x2F;p&gt;
&lt;p&gt;The motivation behind this EIP is to establish a standardized, decentralized, and interoperable approach to index digital media across EVM-compatible networks. By integrating Decentralized Content Identifiers (CIDs) and Commit events, this EIP puts forward a mechanism enabling unique identification and indexing of each digital media file. Moreover, this system suggests a way for users to access a complete history of data associated with digital media assets, from creation to the current status. This full view enhances transparency, thereby providing users with the necessary information for future interactions with digital media.&lt;&#x2F;p&gt;
&lt;p&gt;This method creates a common interface that any digital media system can use to provide a standard way of indexing and searching their content.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7053&#x2F;.&#x2F;assets&#x2F;digital-media-indexing-system-and-metadata-lookup.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;Figure 1: Digital Media Indexing Relationships and Lookup&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;This EIP aims to create an interoperable indexing system to associate all data of the same digital content together (Figure 1). This will make it easier for users to find and trust digital media content, and it will also make it easier for systems to share and exchange information about this digital media content.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;content-identifier&quot;&gt;Content Identifier&lt;&#x2F;h3&gt;
&lt;p&gt;Content Identifier in this EIP is the content address generated by passing the content of a digital media through a cryptographic hash function. Before the indexing process for digital media can begin, it is REQUIRED to generate unique Content Identifiers for each file. This identifier should the same as the Content Identifiers on the decentralized storage, ensuring each identifier provides access to the metadata, media information, and the content file itself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;commit-function&quot;&gt;Commit Function&lt;&#x2F;h3&gt;
&lt;p&gt;To index digital media, we shall call the commit function and generate Commit event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a new commit is made.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; recorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the account making the commit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The content identifier of the asset being committed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The data associated with the commit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recorder&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Registers a commit for an asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Emits a Commit event and records the block number of the commit in the recordLogs mapping for the provided assetCid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits a Commit event and logs the block number of the commit event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The content identifier of the asset being committed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The data associated with the commit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block number at which the commit was made.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; blockNumber&lt;&#x2F;span&gt;&lt;span&gt;)&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;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The design decisions in this EIP prioritize the effectiveness and efficiency of the indexing method. To achieve this, Decentralized Content Identifiers (CIDs) are utilized to uniquely identify digital media content across all systems. This approach offers accurate and precise searching of media, along with the following benefits:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Strengthened data integrity: CIDs serve as cryptographic hashes of the content, ensuring their uniqueness and preventing forgery. With the content in hand, obtaining the CID allows for searching relevant information associated with that content.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Streamlined data portability: CIDs enable the seamless transfer of digital media content across different systems, eliminating the need for re-encoding or reconfiguration of protocols. This promotes a more interoperable and open indexing system. For example, in cases where Non-Fungible Tokens (NFTs) are created prior to Commit events, the digital media content can still be indexed by converting the file referenced by the tokenURI using the same mechanism. This conversion process ensures that the digital media content associated with NFT tokens can be indexed with a consistent identification approach.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;cryptography&#x2F;ECDSA.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts-upgradeable&#x2F;proxy&#x2F;utils&#x2F;Initializable.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CommitRegister&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Initializable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ECDSA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bytes32&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; commitLogs&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recorder&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initialize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; initializer&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; blockNumber&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; commitData&lt;&#x2F;span&gt;&lt;span&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&gt;        commitLogs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;assetCid&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getCommits&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetCid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; commitLogs&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;assetCid&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;When implementing this EIP, it&#x27;s essential to address several security aspects to ensure the safety and integrity of the digital media index:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Input Validation: Given that commit function accepts string parameters, it&#x27;s important to validate these inputs to avoid potential injection attacks. Although such attacks are less common in smart contracts than traditional web development, caution should be exercised.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Data Integrity: The commit function relies on CIDs, which are assumed to be correct and point to the right data. It&#x27;s important to note that this EIP doesn&#x27;t validate the content behind the CIDs and the commit data, which remains a responsibility of the users or implementing applications.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Event Listening: Systems relying on listening to the Commit events for changes need to be aware of potential missed events or incorrect ordering, especially during periods of network congestion or reorganizations.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Implementers should consider these security aspects in the context of their specific use case and deployment scenario. It is strongly recommended to perform a comprehensive security audit before deploying any implementation of this EIP to a live network.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Perpetually Valid Signed Voluntary Exits</title>
        <published>2023-05-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Lion</name><uri>https://github.com/dapplion</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7044/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7044-perpetually-valid-signed-voluntary-exits/14348" />
        

        <id>https://wg-eips.ritovision.com/7044/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7044"
            label="EIP-7044" />
        

        
        

        
        <summary type="html">Lock voluntary exit signature domain on capella for perpetual validity</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7044/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Lock validator voluntary exit signature domain on Capella for perpetual validity. Currently, signed voluntary exits are only valid for two upgrades.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, signed voluntary exits are valid up-to only two upgrades for block inclusion due to the Beacon Chain state considering only the current and previous fork version. This limitation increases the complexity of some staking operations, specifically those in which the staking operator (holder of active key) is distinct from the owner of the funds (holder of the withdrawal credential). Because voluntary exits can only be signed by the active key, such a relationship requires the exchange of signed exits ahead of time for an unbounded number of forks.&lt;&#x2F;p&gt;
&lt;p&gt;The limited validity of voluntary exits was originally motivated to isolate them in the event of a hard fork that results in two maintained chains. If fork A and B exist and a validator operates on both, if they send an exit, it will be replayable on both. However, this possibility is not sufficient to justify the UX degradation exposed above, as no funds are at risk and the staker can re-stake on one or both of the chains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;consensus-layer&quot;&gt;Consensus Layer&lt;&#x2F;h3&gt;
&lt;p&gt;Specification changes are built into the Consensus Specs Deneb upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;The specific makes one change to the state transition function:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Modify &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;75971a8c218b1d76d605dd8b88a08d39c42de221&#x2F;specs&#x2F;deneb&#x2F;beacon-chain.md#modified-process_voluntary_exit&quot;&gt;&lt;code&gt;process_voluntary_exit&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to compute the signing domain and root fixed on &lt;code&gt;CAPELLA_FORK_VERSION&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, the &lt;code&gt;voluntary_exit&lt;&#x2F;code&gt; gossip conditions are implicitly modified to support this change.&lt;&#x2F;p&gt;
&lt;p&gt;To make the change backwards compatible the signature domain is locked on the Capella fork&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution Layer&lt;&#x2F;h3&gt;
&lt;p&gt;This specification does not require any changes to the Execution Layer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Perpetually valid signed voluntary exits allow simpler staking operation designs. It also aligns the UX of such objects to &lt;code&gt;BLSToExecutionChanges&lt;&#x2F;code&gt; and deposits, such that downstream tooling does not need to be updated with fork version information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This change is backwards compatible to the Consensus Layer of Ethereum block processing logic.&lt;&#x2F;p&gt;
&lt;p&gt;The expectation of future validity of exits is not forward compatible. Specifically, users who have already pre-signed exits utilizing the Deneb fork domain with an expectation of their validity should be aware that these pre-signed exits will no longer be recognized as valid. Consequently, users should adjust their approach moving forward. For continued validity across forks, including Deneb and subsequent forks, users should ensure that their exits are signed using the Capella fork domain.&lt;&#x2F;p&gt;
&lt;p&gt;There are no forwards&#x2F;backwards compatibility issues with the Execution Layer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases for this EIP can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;2297c09b7e457a13f7b2261a28cb45777be82f83&#x2F;tests&#x2F;core&#x2F;pyspec&#x2F;eth2spec&#x2F;test&#x2F;deneb&quot;&gt;&lt;code&gt;deneb&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; test suite of the &lt;code&gt;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The divergent signature domains across forked networks would previously have prevented the replay of VoluntaryExits after two hard forks. This specification change causes the replay protection to no longer exist. These potential replays could impact individual stakers on both sides of a fork, but does not put funds at risk and does not impact the security of the chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Increase max attestation inclusion slot</title>
        <published>2023-05-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7045/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7045-increase-attestation-slot-inclusion-range/14342" />
        

        <id>https://wg-eips.ritovision.com/7045/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7045"
            label="EIP-7045" />
        

        
        

        
        <summary type="html">Increases max attestation inclusion slot to the last slot in `N+1` where `N` is the epoch containing the attestation&#x27;s slot.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7045/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Increases max attestation inclusion slot from &lt;code&gt;attestation.slot + SLOTS_PER_EPOCH&lt;&#x2F;code&gt; to the last slot of epoch &lt;code&gt;N+1&lt;&#x2F;code&gt; where &lt;code&gt;N&lt;&#x2F;code&gt; is the epoch containing the attestation slot.&lt;&#x2F;p&gt;
&lt;p&gt;This increase is critical to the current LMD-GHOST security analysis as well as the confirmation rule.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Attestations can currently be included after some minimum delay (&lt;code&gt;1&lt;&#x2F;code&gt; slot on mainnet) up until &lt;code&gt;SLOTS_PER_EPOCH&lt;&#x2F;code&gt; slots after the slot the attestation was created in. This rolling window of one epoch was decided upon during Phase 0 because the equal inclusion window for any attestation was assessed as &quot;fair&quot;. The alternative considered path was to allow inclusion during the current and next epoch which means attestations created during the start of an epoch have more potential slots of inclusion than those at the end of the epoch.&lt;&#x2F;p&gt;
&lt;p&gt;Since this decision, it has become apparent that the alternative design is critical for current LMD-GHOST security proofs as well as a new confirmation rule (which will allow for block confirmations in approximately 3-4 slots in normal mainnet conditions).&lt;&#x2F;p&gt;
&lt;p&gt;This specification thus increases the max inclusion slot for attestations in accordance with the learned security proof and confirmation rule needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_TIMESTAMP&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1710338135&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution layer&lt;&#x2F;h3&gt;
&lt;p&gt;This requires no changes to the Execution Layer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;p&gt;Specification changes are built into the Consensus Specs Deneb upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;The specification makes two minor changes to the state transition function:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Modify &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;95f36d99cf4aa59974da06af24ef9a7c12d3c301&#x2F;specs&#x2F;deneb&#x2F;beacon-chain.md#modified-process_attestation&quot;&gt;&lt;code&gt;process_attestation&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to not have an upper bound on the slot check and instead define the inclusion range via the minimum slot as well as the target epoch being in either current or previous epoch.&lt;&#x2F;li&gt;
&lt;li&gt;Modify &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;95f36d99cf4aa59974da06af24ef9a7c12d3c301&#x2F;specs&#x2F;deneb&#x2F;beacon-chain.md#modified-get_attestation_participation_flag_indices&quot;&gt;&lt;code&gt;get_attestation_participation_flag_indices&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to set the &lt;code&gt;TIMELY_TARGET_FLAG&lt;&#x2F;code&gt; without consideration of &lt;code&gt;inclusion_delay&lt;&#x2F;code&gt; to ensure that the extended inclusion attestations have a non-zero reward.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, the specification modifies the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;95f36d99cf4aa59974da06af24ef9a7c12d3c301&#x2F;specs&#x2F;deneb&#x2F;p2p-interface.md#beacon_attestation_subnet_id&quot;&gt;attestation&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;95f36d99cf4aa59974da06af24ef9a7c12d3c301&#x2F;specs&#x2F;deneb&#x2F;p2p-interface.md#beacon_aggregate_and_proof&quot;&gt;aggregate attestation&lt;&#x2F;a&gt; gossip conditions to allow for gossip during this extended range.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;extended-max-inclusion-slot&quot;&gt;Extended max inclusion slot&lt;&#x2F;h3&gt;
&lt;p&gt;As discussed in the Motivation, extending this max inclusion slot to the end of the next epoch is critical for LMD-GHOST security proofs and confirmation rule.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removal-of-inclusion-delay-consideration-for-target-reward&quot;&gt;Removal of &lt;code&gt;inclusion_delay&lt;&#x2F;code&gt; consideration for target reward&lt;&#x2F;h3&gt;
&lt;p&gt;Previously, &lt;code&gt;get_attestation_participation_flag_indices&lt;&#x2F;code&gt; would only set the &lt;code&gt;TIMELY_TARGET_FLAG&lt;&#x2F;code&gt; (and thus reward for an attestation with correct target vote) if the attestation was included within a &lt;code&gt;SLOTS_PER_EPOCH&lt;&#x2F;code&gt; window.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;inclusion_delay&lt;&#x2F;code&gt; consideration for this flag is removed to ensure that whatever the valid inclusion window is for an attestation, it can receive a baseline non-zero reward for correct target. This ensures that clients will still attempt to pack such attestations into blocks which is important for the security analysis.&lt;&#x2F;p&gt;
&lt;p&gt;Note, this was the intended behavior with the previously defined range which was equivalent to the max.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backwards incompatible changes to the block validation rule set on the consensus layer and must be accompanied by a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases for this EIP can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;2297c09b7e457a13f7b2261a28cb45777be82f83&#x2F;tests&#x2F;core&#x2F;pyspec&#x2F;eth2spec&#x2F;test&#x2F;deneb&quot;&gt;&lt;code&gt;deneb&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; test suite of the &lt;code&gt;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This improves LMD-GHOST security as well as enables a fast confirmation rule.&lt;&#x2F;p&gt;
&lt;p&gt;There are no known negative impacts to security.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Verifiable AI-Generated Content Token</title>
        <published>2023-05-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Cathie So</name><uri>https://github.com/socathie</uri>
	</author>
	
	<author>
		<name>Xiaohang Yu</name><uri>https://github.com/xhyumiracle</uri>
	</author>
	
	<author>
		<name>Conway</name><uri>https://github.com/0x1cc</uri>
	</author>
	
	<author>
		<name>Lee Ting Ting</name><uri>https://github.com/tina1998612</uri>
	</author>
	
	<author>
		<name>Kartin</name><email>kartin@hyperoracle.io</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7007/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7007-zkml-aigc-nfts-an-erc-721-extension-interface-for-zkml-based-aigc-nfts/14216" />
        

        <id>https://wg-eips.ritovision.com/7007/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7007"
            label="ERC-7007" />
        

        
        

        
        <summary type="html">An ERC-721 extension for verifiable AI-generated content tokens using Zero-Knowledge and Optimistic Machine Learning techniques</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7007/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The verifiable AI-generated content (AIGC) non-fungible token (NFT) standard is an extension of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; token standard for AIGC. It proposes a set of interfaces for basic interactions and enumerable interactions for AIGC-NFTs. The standard includes an &lt;code&gt;addAigcData&lt;&#x2F;code&gt; and &lt;code&gt;verify&lt;&#x2F;code&gt; function interface, a new &lt;code&gt;AigcData&lt;&#x2F;code&gt; event, optional &lt;code&gt;Enumerable&lt;&#x2F;code&gt; and &lt;code&gt;Updatable&lt;&#x2F;code&gt; extensions, and a JSON schema for AIGC-NFT metadata. Additionally, it incorporates Zero-Knowledge Machine Learning (zkML) and Optimistic Machine Learning (opML) capabilities to enable verification of AIGC data correctness. In this standard, the &lt;code&gt;tokenId&lt;&#x2F;code&gt; is indexed by the &lt;code&gt;prompt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The verifiable AIGC-NFT standard aims to extend the existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; token standard to accommodate the unique requirements of AI-generated content NFTs representing models in a collection. This standard provides interfaces to use zkML or opML to verify whether or not the AIGC data for an NFT is generated from a certain ML model with a certain input (prompt). The proposed interfaces allow for additional functionality related to adding AIGC data, verifying, and enumerating AIGC-NFTs. Additionally, the metadata schema provides a structured format for storing information related to AIGC-NFTs, such as the prompt used to generate the content and the proof of ownership.&lt;&#x2F;p&gt;
&lt;p&gt;This standard supports two primary types of proofs: validity proofs and fraud proofs. In practice, zkML and opML are commonly employed as the prevailing instances for these types of proofs. Developers can choose their preferred ones.&lt;&#x2F;p&gt;
&lt;p&gt;In the zkML scenario, this standard enables model owners to publish their trained model and its ZKP verifier to Ethereum. Any user can claim an input (prompt) and publish the inference task. Any node that maintains the model and the proving circuit can perform the inference and proving, and submit the output of inference and the ZK proof for the inference trace to the verifier. The user that initiates the inference task will own the output for the inference of that model and input (prompt).&lt;&#x2F;p&gt;
&lt;p&gt;In the opML scenario, this standard enables model owners to publish their trained model to Ethereum. Any user can claim an input (prompt) and publish the inference task. Any node that maintains the model can perform the inference and submit the inference output. Other nodes can challenge this result within a predefined challenge period. At the end of the challenge period, the user can verify that they own the output for the inference of that model and prompt, and update the AIGC data as needed.&lt;&#x2F;p&gt;
&lt;p&gt;This capability is especially beneficial for AI model authors and AI content creators seeking to capitalize on their creations. With this standard, every input prompt and its resulting content can be securely verified on the blockchain. This opens up opportunities for implementing revenue-sharing mechanisms for all AI-generated content (AIGC) NFT sales. AI model authors can now share their models without concerns that open-sourcing will diminish their financial value.&lt;&#x2F;p&gt;
&lt;p&gt;An example workflow of a zkML AIGC NFT project compliant with this proposal is as follows:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;.&#x2F;assets&#x2F;workflow.png&quot; alt=&quot;zkML Suggested Workflow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are 4 components in this workflow:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ML model - contains weights of a pre-trained model; given an inference input, generates the output&lt;&#x2F;li&gt;
&lt;li&gt;zkML prover - given an inference task with input and output, generates a ZK proof&lt;&#x2F;li&gt;
&lt;li&gt;AIGC-NFT smart contract - contract compliant with this proposal, with full &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; functionalities&lt;&#x2F;li&gt;
&lt;li&gt;Verifier smart contract - implements a &lt;code&gt;verify&lt;&#x2F;code&gt; function, given an inference task and its ZK proof, returns the verification result as a boolean&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Every compliant contract must implement the &lt;code&gt;IERC7007&lt;&#x2F;code&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;&lt;code&gt;ERC721&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;&lt;code&gt;ERC165&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; interfaces.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifiable AIGC-NFT standard includes the following interfaces:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;IERC7007&lt;&#x2F;code&gt;: Defines an &lt;code&gt;addAigcData&lt;&#x2F;code&gt; function and an &lt;code&gt;AigcData&lt;&#x2F;code&gt; event for adding AIGC data to AIGC-NFTs. Defines a &lt;code&gt;verify&lt;&#x2F;code&gt; function to check the validity of the combination of prompt and aigcData using zkML&#x2F;opML techniques.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Required interface of an ERC7007 compliant contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x702c55a6.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7007&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `tokenId` token&amp;#39;s AIGC data is added.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AigcData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; aigcData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proof&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add AIGC data to token at `tokenId` given `prompt`, `aigcData`, and `proof`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addAigcData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; aigcData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proof&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify the `prompt`, `aigcData`, and `proof`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; verify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; aigcData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proof&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-extension-enumerable&quot;&gt;Optional Extension: Enumerable&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;strong&gt;enumeration extension&lt;&#x2F;strong&gt; is OPTIONAL for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;&quot;&gt;ERC-7007&lt;&#x2F;a&gt; smart contracts. This allows your contract to publish its full list of mapping between &lt;code&gt;tokenId&lt;&#x2F;code&gt; and &lt;code&gt;prompt&lt;&#x2F;code&gt; and make them discoverable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC7007 Token Standard, optional enumeration extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xfa1a557a.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7007Enumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7007&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the token ID given `prompt`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the prompt given `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-extension-updatable&quot;&gt;Optional Extension: Updatable&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;strong&gt;updatable extension&lt;&#x2F;strong&gt; is OPTIONAL for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;&quot;&gt;ERC-7007&lt;&#x2F;a&gt; smart contracts. This allows your contract to update a token&#x27;s &lt;code&gt;aigcData&lt;&#x2F;code&gt; in the case of opML, where &lt;code&gt;aigcData&lt;&#x2F;code&gt; content might change over the challenge period.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC7007 Token Standard, optional updatable extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x3f37dce2.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7007Updatable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC7007&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Update the `aigcData` of `prompt`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; aigcData&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `tokenId` token is updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; aigcData&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&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;h3 id=&quot;erc-7007-metadata-json-schema-for-reference&quot;&gt;ERC-7007 Metadata JSON Schema for reference&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;AIGC Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prompt&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the prompt from which this AIGC NFT generated&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;aigc_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&#x2F;video&#x2F;audio...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;aigc_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this AIGC NFT represents.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;proof_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;validity (zkML) or fraud (opML)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h3 id=&quot;ml-model-publication&quot;&gt;ML Model Publication&lt;&#x2F;h3&gt;
&lt;p&gt;While this standard does not describe the Machine Learning model publication stage, it is natural and recommended to publish the commitment of the Model to Ethereum separately, before any actual &lt;code&gt;addAigcData&lt;&#x2F;code&gt; actions. The model commitment schema choice lies on the AIGC-NFT project issuer party. The commitment should be checked inside the implementation of the &lt;code&gt;verify&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;unique-token-identification&quot;&gt;Unique Token Identification&lt;&#x2F;h3&gt;
&lt;p&gt;This specification sets the &lt;code&gt;tokenId&lt;&#x2F;code&gt; to be the hash of its corresponding &lt;code&gt;prompt&lt;&#x2F;code&gt;, creating a deterministic and collision-resistant way to associate tokens with their unique content generation parameters. This design decision ensures that the same prompt (which corresponds to the same AI-generated content under the same model seed) cannot be minted more than once, thereby preventing duplication and preserving the uniqueness of each NFT within the ecosystem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generalization-to-different-proof-types&quot;&gt;Generalization to Different Proof Types&lt;&#x2F;h3&gt;
&lt;p&gt;This specification accommodates two proof types: validity proofs for zkML and fraud proofs for opML. Function arguments in &lt;code&gt;addAigcData&lt;&#x2F;code&gt; and &lt;code&gt;verify&lt;&#x2F;code&gt; are designed for generality, allowing for compatibility with both proof systems. Moreover, the specification includes an updatable extension that specifically serves the requirements of opML.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;verify-interface&quot;&gt;&lt;code&gt;verify&lt;&#x2F;code&gt; interface&lt;&#x2F;h3&gt;
&lt;p&gt;We specify a &lt;code&gt;verify&lt;&#x2F;code&gt; interface to enforce the correctness of &lt;code&gt;aigcData&lt;&#x2F;code&gt;. It is defined as a view function to reduce gas cost. &lt;code&gt;verify&lt;&#x2F;code&gt; should return true if and only if &lt;code&gt;aigcData&lt;&#x2F;code&gt; is finalized in both zkML and opML. In zkML, it must verify the ZK proof, i.e. &lt;code&gt;proof&lt;&#x2F;code&gt;; in opML, it must make sure that the challenging period is finalized, and that the &lt;code&gt;aigcData&lt;&#x2F;code&gt; is up-to-date, i.e. has been updated after finalization. Additionally, &lt;code&gt;proof&lt;&#x2F;code&gt; can be &lt;em&gt;empty&lt;&#x2F;em&gt; in opML.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;addaigcdata-interface&quot;&gt;&lt;code&gt;addAigcData&lt;&#x2F;code&gt; interface&lt;&#x2F;h3&gt;
&lt;p&gt;We specify an &lt;code&gt;addAigcData&lt;&#x2F;code&gt; interface to bind the prompt and &lt;code&gt;aigcData&lt;&#x2F;code&gt; with &lt;code&gt;tokenId&lt;&#x2F;code&gt;. This function provides flexibility for different minting implementations. Notably, it acts differently in zkML and opML cases. In zkML, &lt;code&gt;addAigcData&lt;&#x2F;code&gt; should make sure &lt;code&gt;verify&lt;&#x2F;code&gt; returns &lt;code&gt;true&lt;&#x2F;code&gt;. While in opML, it can be called before finalization. The consideration here is that, limited by the proving difficulty, zkML usually targets simple model inference tasks in practice, making it possible to provide a proof within an acceptable time frame. On the other hand, opML enables large model inference tasks, with a cost of longer confirmation time to achieve the approximate same security level. Mint until opML finalization may not be the best practice considering the existing optimistic protocols.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;naming-choice-on-update&quot;&gt;Naming Choice on &lt;code&gt;update&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;We adopt &quot;update&quot; over &quot;finalize&quot; because a successful challenge happens rarely in practice. Using &lt;code&gt;update&lt;&#x2F;code&gt; could avoid calling it for every &lt;code&gt;tokenId&lt;&#x2F;code&gt; and save gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is backward compatible with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; as it extends the existing functionality with new interfaces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The reference implementation includes sample implementations of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;&quot;&gt;ERC-7007&lt;&#x2F;a&gt; interfaces under &lt;code&gt;contracts&#x2F;&lt;&#x2F;code&gt; and corresponding unit tests under &lt;code&gt;test&#x2F;&lt;&#x2F;code&gt;. This repo can be used to test the functionality of the proposed interfaces and metadata schema.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;ERC-7007 for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC7007Zkml.sol&quot;&gt;zkML&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC7007Opml.sol&quot;&gt;opML&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7007&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC7007Enumerable.sol&quot;&gt;ERC-7007 Enumerable Extension&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;frontrunning-risk&quot;&gt;Frontrunning Risk&lt;&#x2F;h3&gt;
&lt;p&gt;To address the risk of frontrunning, where an actor could potentially observe and preemptively claim a prompt during the minting process, implementers of this proposal must incorporate a secure prompt-claiming mechanism. Implementations could include time-locks, commit-reveal schemes, or other anti-frontrunning techniques to ensure equitable and secured claim processes for AIGC-NFTs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aigc-data-change-during-challenge-period&quot;&gt;AIGC Data Change During Challenge Period&lt;&#x2F;h3&gt;
&lt;p&gt;In the opML scenario, it is important to consider that the &lt;code&gt;aigcData&lt;&#x2F;code&gt; might change during the challenge period due to disputes or updates. The updatable extension defined here provides a way to handle these updates. Implementations must ensure that updates to &lt;code&gt;aigcData&lt;&#x2F;code&gt; are treated as critical state changes that require adherence to the same security and validation protocols as the initial minting process. Indexers should always check for any &lt;code&gt;Update&lt;&#x2F;code&gt; event emission.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Execution layer triggerable withdrawals</title>
        <published>2023-05-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Mikhail Kalinin</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	<author>
		<name>Hsiao-Wei Wang</name><uri>https://github.com/hwwhww</uri>
	</author>
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	<author>
		<name>Felix Lange</name><uri>https://github.com/fjl</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7002/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-7002-execution-layer-triggerable-exits/14195" />
        

        <id>https://wg-eips.ritovision.com/7002/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:7002"
            label="EIP-7002" />
        

        
        

        
        <summary type="html">Allow validators to trigger exits and partial withdrawals via their execution layer (0x01) withdrawal credentials</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7002/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Adds a new mechanism to allow validators to trigger withdrawals and exits from their execution layer (0x01) withdrawal credentials.&lt;&#x2F;p&gt;
&lt;p&gt;These new execution layer exit messages are appended to the execution layer block and then processed by the consensus layer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Validators have two keys -- an active key and a withdrawal credential. The active key takes the form of a BLS key, whereas the withdrawal credential can either be a BLS key (0x00) or an execution layer address (0x01). The active key is &quot;hot&quot;, actively signing and performing validator duties, whereas the withdrawal credential can remain &quot;cold&quot;, only performing limited operations in relation to withdrawing and ownership of the staked ETH. Due to this security relationship, the withdrawal credential ultimately is the key that owns the staked ETH and any rewards.&lt;&#x2F;p&gt;
&lt;p&gt;As currently specified, only the active key can initiate a validator exit. This means that in any non-standard custody relationship (i.e., the active key is a separate entity from the withdrawal credentials), the ultimate owner of the funds -- the possessor of the withdrawal credentials -- cannot independently choose to exit and begin the withdrawal process. This leads to either trust issues (e.g. ETH can be &quot;held hostage&quot; by the active key owner) or insufficient work-arounds such as pre-signed exits. Additionally, in the event that active keys are lost, a user should still be able to recover their funds by using their cold withdrawal credentials.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure that the withdrawal credentials (owned by both EOAs and smart contracts) can trustlessly control the destiny of the staked ETH, this specification enables exits triggerable by 0x01 withdrawal credentials.&lt;&#x2F;p&gt;
&lt;p&gt;Note, 0x00 withdrawal credentials can be changed into 0x01 withdrawal credentials with a one-time signed message. Thus any functionality enabled for 0x01 credentials is defacto enabled for 0x00 credentials.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00000961Ef480Eb55e80D19ad83579A64c007002&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Where to call and store relevant details about exit &#x2F; partial withdrawal mechanism&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_TYPE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x01&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; type prefix for withdrawal request&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address used to invoke system operation on contract&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Pointer to head of the withdrawal request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Pointer to the tail of the withdrawal request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;The start memory slot of the in-state withdrawal request message queue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;Maximum number of withdrawal requests that can be dequeued into a block&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_WITHDRAWAL_REQUEST_FEE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXCESS_INHIBITOR&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**256-1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Excess value used to compute the fee before the first system call&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution layer&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; -- the first block in a blockchain after this EIP has been activated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;withdrawal-request-operation&quot;&gt;Withdrawal request operation&lt;&#x2F;h4&gt;
&lt;p&gt;The new withdrawal request operation is an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; request
with type &lt;code&gt;0x01&lt;&#x2F;code&gt; and consists of the following fields:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;source_address&lt;&#x2F;code&gt;: &lt;code&gt;Bytes20&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;validator_pubkey&lt;&#x2F;code&gt;: &lt;code&gt;Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: &lt;code&gt;uint64&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; encoding of a withdrawal request is computed as follows.
Note that &lt;code&gt;amount&lt;&#x2F;code&gt; is returned by the contract little-endian, and must be encoded as such.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; read_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;withdrawal-request-contract&quot;&gt;Withdrawal Request Contract&lt;&#x2F;h4&gt;
&lt;p&gt;The contract has three different code paths, which can be summarized at a high level as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add withdrawal request - requires a &lt;code&gt;56&lt;&#x2F;code&gt; byte input, the validator&#x27;s public
key concatenated with a big-endian &lt;code&gt;uint64&lt;&#x2F;code&gt; amount value.&lt;&#x2F;li&gt;
&lt;li&gt;Fee getter - if the input length is zero, return the current fee required to add a withdrawal request.&lt;&#x2F;li&gt;
&lt;li&gt;System process - if called by system address, pop off the withdrawal requests for the current block from the queue.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h5 id=&quot;add-withdrawal-request&quot;&gt;Add Withdrawal Request&lt;&#x2F;h5&gt;
&lt;p&gt;If call data input to the contract is exactly &lt;code&gt;56&lt;&#x2F;code&gt; bytes, perform the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure enough ETH was sent to cover the current withdrawal request fee (&lt;code&gt;check_fee()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Increase withdrawal request count by 1 for the current block (&lt;code&gt;increment_count()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Insert a withdrawal request into the queue for the source address and validator pubkey (&lt;code&gt;insert_withdrawal_request_into_queue()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Specifically, the functionality is defined in pseudocode as the function &lt;code&gt;add_withdrawal_request()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add_withdrawal_request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;Bytes48&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; validator_pubkey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Add withdrawal request adds new request to the withdrawal request queue, so long as a sufficient fee is provided.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify sufficient fee was provided.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_fee&lt;&#x2F;span&gt;&lt;span&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&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; fee&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Insufficient value for fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increment withdrawal request count.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Insert into queue.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; validator_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; validator_pubkey&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt; uint64_to_little_endian&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h6 id=&quot;fee-calculation&quot;&gt;Fee calculation&lt;&#x2F;h6&gt;
&lt;p&gt;The following pseudocode can compute the cost of an individual withdrawal request, given a certain number of excess withdrawal requests.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_fee&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_INHIBITOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Inhibitor still active&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        MIN_WITHDRAWAL_REQUEST_FEE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        excess&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; denominator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;denominator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;fee-getter&quot;&gt;Fee Getter&lt;&#x2F;h5&gt;
&lt;p&gt;When the input to the contract is length zero, interpret this as a get request for the current fee, i.e. the contract returns the result of &lt;code&gt;get_fee()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;system-call&quot;&gt;System Call&lt;&#x2F;h5&gt;
&lt;p&gt;At the end of processing any execution block starting from the &lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt; (i.e. after processing all transactions and after performing the block body withdrawal requests validations), call &lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; as &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; with no calldata. The invocation triggers the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The contract&#x27;s queue is updated based on withdrawal requests dequeued and the withdrawal requests queue head&#x2F;tail are reset if the queue has been cleared (&lt;code&gt;dequeue_withdrawal_requests()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;The contract&#x27;s excess withdrawal requests are updated based on usage in the current block (&lt;code&gt;update_excess_withdrawal_requests()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;The contract&#x27;s withdrawal requests count is reset to 0 (&lt;code&gt;reset_withdrawal_requests_count()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each withdrawal request must appear in the EIP-7685 requests list in the exact order returned by &lt;code&gt;dequeue_withdrawal_requests()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the system call and the processing of that block must conform to the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The call has a dedicated gas limit of &lt;code&gt;30_000_000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Gas consumed by this call does not count against the block’s overall gas usage.&lt;&#x2F;li&gt;
&lt;li&gt;Both the gas limit assigned to the call and the gas consumed are excluded from any checks against the block’s gas limit.&lt;&#x2F;li&gt;
&lt;li&gt;The call does not follow &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt; fee burn semantics — no value should be transferred as part of this call.&lt;&#x2F;li&gt;
&lt;li&gt;If there is no code at &lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt;, the corresponding block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be marked invalid.&lt;&#x2F;li&gt;
&lt;li&gt;If the call to the contract fails or returns an error, the block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be invalidated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The functionality triggered by the system call is defined in pseudocode as the function &lt;code&gt;read_withdrawal_requests()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;##################&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Public function #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; read_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    reqs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dequeue_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&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&gt;    update_excess_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&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&gt;    reset_withdrawal_requests_count&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ssz&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;serialize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;reqs&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;##########&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Helpers #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; little_endian_to_uint64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;little&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; uint64_to_little_endian&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;num&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;little&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ValidatorWithdrawalRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;object&lt;&#x2F;span&gt;&lt;span&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&gt;    source_address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    validator_pubkey&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    amount&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; dequeue_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    num_in_queue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; queue_head_index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    num_dequeued&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;num_in_queue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;span&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&gt;    reqs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;num_dequeued&lt;&#x2F;span&gt;&lt;span&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&gt;        queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        source_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&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&gt;        validator_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; little_endian_to_uint64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; queue_storage_slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&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&gt;        req&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ValidatorWithdrawalRequest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;            source_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Bytes20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;source_address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;            validator_pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Bytes48&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;validator_pubkey&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;            amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        reqs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;req&lt;&#x2F;span&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&gt;    new_queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; num_dequeued&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; new_queue_head_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; queue_tail_index&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Queue is empty, reset queue pointers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&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&gt;        sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_queue_head_index&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; reqs&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; update_excess_withdrawal_requests&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_INHIBITOR&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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;    count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&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&gt;    new_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        new_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; previous_excess&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&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;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; new_excess&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; reset_withdrawal_requests_count&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    sstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;bytecode&quot;&gt;Bytecode&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push20 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xcb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push32 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iszero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x68&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;div&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;div&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x38&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x88&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;callvalue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;callvalue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x38&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatacopy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x10&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0183&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push32 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffff00000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x38&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x07&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x06&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x04&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x08&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;shr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xe1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0195&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push32 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iszero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01cd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01e2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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 class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;push2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01e8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jump&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x02&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;sub&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;mul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;deployment&quot;&gt;Deployment&lt;&#x2F;h5&gt;
&lt;p&gt;The withdrawal requests contract is deployed like any other smart contract. A special synthetic address is generated by working backwards from the desired deployment transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3d090&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe8d4a51000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxPriorityFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f556101f880602d5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x539&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x5feeb084551e4e03a3581e269bc2ea2f8d0008&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8ded54be89448d78d4bc97782c0187b099e45380ab681742f9d3754e405c2572&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sender: 0x8646861A7cF453dDD086874d622b0696dE5b9674&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Address: 0x00000961Ef480Eb55e80D19ad83579A64c007002&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;7bf43d1bc4fdb91059f0e6f4f7f0f3349b144950&#x2F;specs&#x2F;electra&#x2F;beacon-chain.md&quot;&gt;Full specification&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sketch of spec:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;New operation &lt;code&gt;ExecutionLayerWithdrawalRequest&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Will show up in &lt;code&gt;ExecutionPayload&lt;&#x2F;code&gt; as an SSZ List bound by length &lt;code&gt;MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;New function that has similar functionality to &lt;code&gt;process_voluntary_exit&lt;&#x2F;code&gt; but can fail validations (e.g. validator is already exited) without the block failing (similar to deposit coming from EL)&lt;&#x2F;li&gt;
&lt;li&gt;This function is called in &lt;code&gt;process_operations&lt;&#x2F;code&gt; for each &lt;code&gt;ExecutionLayerWithdrawalRequest&lt;&#x2F;code&gt; found in the &lt;code&gt;ExecutionPayload&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;validator-pubkey-field&quot;&gt;&lt;code&gt;validator_pubkey&lt;&#x2F;code&gt; field&lt;&#x2F;h3&gt;
&lt;p&gt;Multiple validators can utilize the same execution layer withdrawal credential, thus the &lt;code&gt;validator_pubkey&lt;&#x2F;code&gt; field is utilized to disambiguate which validator is being exited.&lt;&#x2F;p&gt;
&lt;p&gt;Note, &lt;code&gt;validator_index&lt;&#x2F;code&gt; also disambiguates validators.
The problem is that smart contracts of some staking pools are not aware of the indices, because the index becomes known only after the validator has been created on the beacon chain, while the pubkey is available in advance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;message-queue&quot;&gt;Message queue&lt;&#x2F;h3&gt;
&lt;p&gt;The contract maintains an in-state queue of withdrawal request messages to be dequeued each block into the block and thus into the execution layer.&lt;&#x2F;p&gt;
&lt;p&gt;The number of withdrawal requests that can be passed into the consensus layer are bound by &lt;code&gt;MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; to bound the load both on the block size as well as on the consensus layer processing. &lt;code&gt;16&lt;&#x2F;code&gt; has been chosen for &lt;code&gt;MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; to be in line with the bounds of similar operations on the beacon chain -- e.g. &lt;code&gt;VoluntaryExit&lt;&#x2F;code&gt; and &lt;code&gt;Deposit&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Although there is a maximum number of withdrawal requests that can be passed to the consensus layer each block, the execution layer gas limit can provide for far more calls to the withdrawal request predeploy contract at each block. The queue then allows for these calls to successfully be made while still maintaining a system rate limit.&lt;&#x2F;p&gt;
&lt;p&gt;The alternative design considered was to have calls to the contract fail after &lt;code&gt;MAX_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; successful calls were made within the context of a single block. This would eliminate the need for the message queue, but would come at the cost of a bad UX of contract call failures in times of high exiting. The complexity to mitigate this bad UX is relatively low and is currently favored.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rate-limiting-using-a-fee&quot;&gt;Rate limiting using a fee&lt;&#x2F;h3&gt;
&lt;p&gt;Transactions are naturally rate-limited in the execution layer via the gas limit, but an adversary willing to pay market-rate gas fees (and potentially utilize builder markets to pay for front-of-block transaction inclusion) can fill up the exit operation limits for relatively cheap, thus griefing honest validators that want to make a withdrawal request.&lt;&#x2F;p&gt;
&lt;p&gt;There are two general approaches to combat this griefing -- (a) only allow validators to send such messages and with a limit per time period or (b) utilize an economic method to make such griefing increasingly costly.&lt;&#x2F;p&gt;
&lt;p&gt;Method (a) (not used in this EIP) would require &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt; (the &lt;code&gt;BEACON_ROOT&lt;&#x2F;code&gt; opcode) against which to prove withdrawal credentials in relation to validator pubkeys as well as a data-structure to track requests per-unit-time (e.g. 4 months) to ensure that a validator cannot grief the mechanism by submitting many requests. The downsides of this method are that it requires another cross-layer EIP and that it is of higher cross-layer complexity (e.g. care that might need to be taken in future upgrades if, for example, the shape of the merkle tree of &lt;code&gt;BEACON_ROOT&lt;&#x2F;code&gt; changes, then the contract and proof structure might need to be updated).&lt;&#x2F;p&gt;
&lt;p&gt;Method (b) has been utilized in this EIP to eliminate additional EIP requirements and to reduce cross-layer complexity to allow for correctness of this EIP (now and in the future) to be easier to analyze. The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt;-style mechanism with a dynamically adjusting fee mechanism allows for users to pay &lt;code&gt;MIN_WITHDRAWAL_REQUEST_FEE&lt;&#x2F;code&gt; for withdrawal requests in the normal case (fewer than 2 per block on average), but scales the fee up exponentially in response to high usage (i.e. potential abuse).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;target-withdrawal-requests-per-block-configuration-value&quot;&gt;&lt;code&gt;TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; configuration value&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; has been selected as &lt;code&gt;2&lt;&#x2F;code&gt; such that the growth of the partial withdrawal queue in the beacon state is negligible under extreme scenarios of the exit churn congestion.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fee-update-rule&quot;&gt;Fee update rule&lt;&#x2F;h3&gt;
&lt;p&gt;The fee update rule is intended to approximate the formula &lt;code&gt;fee = MIN_WITHDRAWAL_REQUEST_FEE * e**(excess &#x2F; WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION)&lt;&#x2F;code&gt;, where &lt;code&gt;excess&lt;&#x2F;code&gt; is the total &quot;extra&quot; amount of withdrawal requests that the chain has processed relative to the &quot;targeted&quot; number (&lt;code&gt;TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt; per block).&lt;&#x2F;p&gt;
&lt;p&gt;Like EIP-1559, it’s a self-correcting formula: as the excess goes higher, the &lt;code&gt;fee&lt;&#x2F;code&gt; increases exponentially, reducing usage and eventually forcing the excess back down.&lt;&#x2F;p&gt;
&lt;p&gt;The block-by-block behavior is roughly as follows. If block &lt;code&gt;N&lt;&#x2F;code&gt; processes &lt;code&gt;X&lt;&#x2F;code&gt; requests, then at the end of block &lt;code&gt;N&lt;&#x2F;code&gt; &lt;code&gt;excess&lt;&#x2F;code&gt; increases by &lt;code&gt;X - TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK&lt;&#x2F;code&gt;, and so the &lt;code&gt;fee&lt;&#x2F;code&gt; in block &lt;code&gt;N+1&lt;&#x2F;code&gt; increases by a factor of &lt;code&gt;e**((X - TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK) &#x2F; WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION)&lt;&#x2F;code&gt;. Hence, it has a similar effect to the existing EIP-1559, but is more &quot;stable&quot; in the sense that it responds in the same way to the same total withdrawal requests regardless of how they are distributed over time.&lt;&#x2F;p&gt;
&lt;p&gt;The parameter &lt;code&gt;WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt; controls the maximum downwards rate of change of the blob gas price. It is chosen to target a maximum downwards change rate of &lt;code&gt;e(TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK &#x2F; WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION) ≈ 1.125&lt;&#x2F;code&gt; per block.&lt;&#x2F;p&gt;
&lt;p&gt;More detailed analysis of the fee mechanism is available &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7002&#x2F;assets&#x2F;fee_analysis&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;withdrawal-requests-inside-of-the-block&quot;&gt;Withdrawal requests inside of the block&lt;&#x2F;h3&gt;
&lt;p&gt;Withdrawal requests are placed into the actual body of the beacon block.&lt;&#x2F;p&gt;
&lt;p&gt;There is a strong design requirement that the consensus layer and execution layer can execute independently of each other. This means, in this case, that the consensus layer cannot rely upon a synchronous call to the execution layer to get the required withdrawal requests for the current block. Instead, the requests must be embedded in the beacon block such that if the execution layer is offline, the consensus layer still has the requisite data to fully execute the consensus portion of the state transition function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;submitting-requests-via-execution-layer&quot;&gt;Submitting requests via execution layer&lt;&#x2F;h3&gt;
&lt;p&gt;Verifying &lt;code&gt;secp256k1&lt;&#x2F;code&gt; signatures from the consensus layer via Engine API is one of the alternatives to the proposed requests mechanism which engineering complexity is much lower.
However, this approach would limit usage of withdrawal requests to a large extent by making it impossible for smart contracts owning validator withdrawal credentials to benefit from this functionality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backwards incompatible changes to the block structure and block validation rule set. But neither of these changes break anything related to current user activity and experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;impact-on-existing-custody-relationships&quot;&gt;Impact on existing custody relationships&lt;&#x2F;h3&gt;
&lt;p&gt;There might be existing custody relationships and&#x2F;or products that rely upon the assumption that the withdrawal credentials &lt;em&gt;cannot&lt;&#x2F;em&gt; trigger a withdrawal request. We are currently confident that the additional withdrawal credentials feature does not impact the security of existing validators because:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The withdrawal credentials ultimately own the funds so allowing them to exit staking is natural with respect to ownership.&lt;&#x2F;li&gt;
&lt;li&gt;We are currently not aware of any such custody relationships and&#x2F;or products that do rely on the lack of this feature.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In the event that existing validators&#x2F;custodians rely on this, then the validators can be exited and restaked utilizing 0x01 withdrawal credentials pointing to a smart contract that simulates this behaviour.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fee-overpayment&quot;&gt;Fee Overpayment&lt;&#x2F;h3&gt;
&lt;p&gt;Calls to the system contract require a fee payment defined by the current contract state. Overpaid fees are not returned to the caller. It is not generally possible to compute the exact required fee amount ahead of time. When adding a withdrawal request from a contract, the contract can perform a read operation to check for the current fee and then pay exactly the required amount. Here is an example in Solidity:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function addWithdrawal(bytes memory pubkey, uint64 amount, uint64 requestFeeLimit) private {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(pubkey.length == 48);&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; Read current fee from the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (bool readOK, bytes memory feeData) = WithdrawalsContract.staticcall(&amp;#39;&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (!readOK) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;reading fee failed&amp;#39;);&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;    uint256 fee = uint256(bytes32(feeData));&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; Check the fee is not too high.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (fee &amp;gt; requestFeeLimit) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;fee is too high&amp;#39;);&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&gt;    &#x2F;&#x2F; Add the request.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes memory callData = abi.encodePacked(pubkey, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (bool writeOK,) = WithdrawalsContract.call{value: fee}(callData);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (!writeOK) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        revert(&amp;#39;adding request failed&amp;#39;);&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;Note: the system contract uses the EVM &lt;code&gt;CALLER&lt;&#x2F;code&gt; operation (Solidity: &lt;code&gt;msg.sender&lt;&#x2F;code&gt;) as the target address for withdrawals, i.e. the address that calls the system contract must match the 0x01 withdrawal credential recorded in the beacon state.&lt;&#x2F;p&gt;
&lt;p&gt;Note: the above code reverts if the fee is too high, the fee can change significantly between creation of a withdrawal request transaction and its inclusion into a block, thus, this check is very important to avoid overpayments.&lt;&#x2F;p&gt;
&lt;p&gt;Using an EOA to request withdrawals will always result in overpayment of fees. There is no way for an EOA to use a wrapper contract to request a withdrawal. And even if a way existed, the gas cost of returning the overage would likely be higher than the overage itself. If requesting withdrawals to an EOA through the system contract is desired, we recommend that users perform transaction simulations to estimate a reasonable fee amount to send.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-call-failure&quot;&gt;System Call failure&lt;&#x2F;h3&gt;
&lt;p&gt;Although the likelihood of a failed system call to &lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; is extremely low, the behavior in such cases is well-defined: the block is marked as invalid. However, if the failure results from processing a transaction within the block, the public mempool may still retain the transaction even after the block is invalidated. This can result in the offending transaction being included again, potentially causing one or more subsequent slots to go without valid blocks. To mitigate this, we recommend that the block producer implementation shuffle their transaction set to increase the chances of producing a valid block, without the offending transaction(s). The block producer implementation and&#x2F;or the mempool should be aware of system call failure scenarios to enable this behavior.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;empty-code-failure&quot;&gt;Empty Code failure&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP should not have been activated if there is no code present at &lt;code&gt;WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS&lt;&#x2F;code&gt; (i.e., if the chain is not &quot;ready&quot;). Doing so would cause the first and all subsequent blocks after &lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt; to be marked invalid.&lt;&#x2F;p&gt;
&lt;p&gt;If this situation occurs on a live chain, the following are two potential recovery strategies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Deploy the contract code via a transaction and include it in a block. This block would become the first valid block, provided the system call to the contract does not fail. This works because the empty code validation occurs after block-transactions execution.&lt;&#x2F;li&gt;
&lt;li&gt;Postpone the &lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt; activation point by updating the consensual fork timestamp or block number in the client implementation(s), then deploy the contract before the fork activates.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Efficient Default Lockable Tokens</title>
        <published>2023-05-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Francesco Sullo</name><uri>https://github.com/sullof</uri>
	</author>
	
	<author>
		<name>Alexe Spataru</name><uri>https://github.com/urataps</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6982/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc721-default-lockable-proposal/13366" />
        

        <id>https://wg-eips.ritovision.com/6982/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6982"
            label="ERC-6982" />
        

        
        

        
        <summary type="html">A gas-efficient approach to lockable ERC-721 tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6982/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces a lockable interface for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; tokens that optimizes gas usage by eliminating unnecessary events. This interface forms the foundation for the creation and management of lockable &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; tokens. It provides a gas-efficient approach by emitting a &lt;code&gt;DefaultLocked(bool locked)&lt;&#x2F;code&gt; event upon deployment, setting the initial lock status for all tokens, while individual &lt;code&gt;Locked(uint256 indexed tokenId, bool locked)&lt;&#x2F;code&gt; events handle subsequent status changes for specific tokens. The interface also includes a view function &lt;code&gt;locked(uint256 tokenId)&lt;&#x2F;code&gt; to return the current lock status of a token, and a view function &lt;code&gt;defaultLocked()&lt;&#x2F;code&gt; to query the default status of a newly minted token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Existing lockable token proposals often mandate the emission of an event each time a token is minted. This results in unnecessary gas consumption, especially in cases where tokens are permanently locked from inception to destruction (e.g., soulbounds or non-transferable badges). This proposal offers a more gas-efficient solution that only emits events upon contract deployment and status changes of individual tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;The interface is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interfaceId 0x6b61a747&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6982&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when the contract is deployed to establish the default lock status &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      for all tokens. Also, MUST be emitted again if the default lock status changes, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      to ensure the default status for all tokens (without a specific `Locked` event) is updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DefaultLocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; locked&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST be emitted when the lock status of a specific token changes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      This status overrides the default lock status for that specific token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Locked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; locked&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current default lock status for tokens. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      The returned value MUST reflect the status indicated by the most recent `DefaultLocked` event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; defaultLocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the lock status of a specific token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      If no `Locked` event has been emitted for the token, it MUST return the current default lock status. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *      The function MUST revert if the token does not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; locked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interfaceId is &lt;code&gt;0x6b61a747&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standard seeks to optimize gas consumption by minimizing the frequency of event emission. The &lt;code&gt;DefaultLocked&lt;&#x2F;code&gt; event is designed to establish the lock status for all tokens, thereby circumventing the need to emit an event each time a new token is minted. It&#x27;s crucial to note that the &lt;code&gt;DefaultLocked&lt;&#x2F;code&gt; event can be emitted at any point in time, and is not restricted to only before the &lt;code&gt;Locked&lt;&#x2F;code&gt; events are emitted.&lt;&#x2F;p&gt;
&lt;p&gt;Tokens may alter their behavior under certain circumstances (such as after a reveal), prompting the re-emission of the &lt;code&gt;DefaultLocked&lt;&#x2F;code&gt; event to reflect the new default status. The primary objective here is to economize on gas usage by avoiding the need to emit a &lt;code&gt;Locked&lt;&#x2F;code&gt; event for each token when the default status changes.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Locked&lt;&#x2F;code&gt; event is utilized to document changes in the lock status of individual tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;defaultLocked&lt;&#x2F;code&gt; function returns the prevailing default lock status of a token. This function is beneficial as it fosters interaction with other contracts and averts potential conflicts with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5192&#x2F;&quot;&gt;ERC-5192&lt;&#x2F;a&gt;, which is in its final stage.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;locked&lt;&#x2F;code&gt; function gives the current lock status of a particular token, further facilitating interaction with other contracts. If no changes have been made to a specific token ID, this function should return the value provided by the &lt;code&gt;defaultLocked&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;Bear in mind that a token being designated as &quot;locked&quot; doesn&#x27;t necessarily imply that it is entirely non-transferable. There might be certain conditions under which a token can still be transferred despite its locked status. Primarily, the locked status relates to a token&#x27;s transferability on marketplaces and external exchanges.&lt;&#x2F;p&gt;
&lt;p&gt;To illustrate, let&#x27;s consider the Cruna protocol. In this system, an NFT owner has the ability to activate what is termed an &#x27;protector&#x27;. This is essentially a secondary wallet with the unique privilege of initiating key transactions. Upon setting an initiator, the token&#x27;s status is rendered &#x27;locked&#x27;. However, this does not impede the token&#x27;s transferability if the initiation for the transfer comes from the designated protector.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully backwards compatible with existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; contracts. It can be easily integrated into existing contracts and will not cause any conflicts or disruptions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;An example implementation is located in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6982&#x2F;assets&#x2F;README&#x2F;&quot;&gt;assets&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It solves a specific use case: token&#x27;s owners losing the ownership when staking the asset in a pool. The implementation allow the pool to lock the asset, leaving the ownership to the owner. In the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6982&#x2F;assets&#x2F;README&#x2F;&quot;&gt;README&lt;&#x2F;a&gt; you can find more details about how to compile and test the contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce any known security considerations. However, as with any smart contract standard, it is crucial to employ rigorous security measures in the implementation of this interface.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multi Injected Provider Discovery</title>
        <published>2023-05-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Pedro Gomes</name><uri>https://github.com/pedrouid</uri>
	</author>
	
	<author>
		<name>Kosala Hemachandra</name><uri>https://github.com/kvhnuke</uri>
	</author>
	
	<author>
		<name>Richard Moore</name><uri>https://github.com/ricmoo</uri>
	</author>
	
	<author>
		<name>Gregory Markou</name><uri>https://github.com/GregTheGreek</uri>
	</author>
	
	<author>
		<name>Kyle Den Hartog</name><uri>https://github.com/kdenhartog</uri>
	</author>
	
	<author>
		<name>Glitch</name><uri>https://github.com/glitch-txs</uri>
	</author>
	
	<author>
		<name>Jake Moxey</name><uri>https://github.com/jxom</uri>
	</author>
	
	<author>
		<name>Pierre Bertet</name><uri>https://github.com/bpierre</uri>
	</author>
	
	<author>
		<name>Darryl Yeo</name><uri>https://github.com/darrylyeo</uri>
	</author>
	
	<author>
		<name>Yaroslav Sergievsky</name><uri>https://github.com/everdimension</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6963/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6963-multi-injected-provider-interface-aka-mipi/14076" />
        

        <id>https://wg-eips.ritovision.com/6963/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:6963"
            label="EIP-6963" />
        

        
        

        
        <summary type="html">Using window events to announce injected Wallet Providers</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6963/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;An alternative discovery mechanism to &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt; providers which supports discovering multiple injected Wallet Providers in a web page using Javascript&#x27;s &lt;code&gt;window&lt;&#x2F;code&gt; events.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, Wallet Provider that offer browser extensions must inject their Ethereum providers (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;) into the same window object &lt;code&gt;window.ethereum&lt;&#x2F;code&gt;; however, this creates conflicts for users that may install more than one browser extension.&lt;&#x2F;p&gt;
&lt;p&gt;Browser extensions are loaded in the web page in an unpredictable and unstable order, resulting in a race condition where the user does not have control over which Wallet Provider is selected to expose the Ethereum interface under the &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; object. Instead, the last wallet to load usually wins.&lt;&#x2F;p&gt;
&lt;p&gt;This results not only in a degraded user experience but also increases the barrier to entry for new browser extensions as users are forced to only install one browser extension at a time.&lt;&#x2F;p&gt;
&lt;p&gt;Some browser extensions attempt to counteract this problem by delaying their injection to overwrite the same &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; object which creates an unfair competition for Wallet Providers and lack of interoperability.&lt;&#x2F;p&gt;
&lt;p&gt;In this proposal, we present a solution that focuses on optimizing the interoperability of multiple Wallet Providers. This solution aims to foster fairer competition by reducing the barriers to entry for new Wallet Providers, along with enhancing the user experience on Ethereum networks.&lt;&#x2F;p&gt;
&lt;p&gt;This is achieved by introducing a set of window events to provide a two-way communication protocol between Ethereum libraries and injected scripts provided by browser extensions thus enabling users to select their wallet of choice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2119&quot;&gt;RFC-2119&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;Wallet Provider: A user agent that manages keys and facilitates transactions with Ethereum.&lt;&#x2F;p&gt;
&lt;p&gt;Decentralized Application (DApp): A web page that relies upon one or many Web3 platform APIs which are exposed to the web page via the Wallet.&lt;&#x2F;p&gt;
&lt;p&gt;Provider Discovery Library: A library or piece of software that assists a DApp to interact with the Wallet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;provider-info&quot;&gt;Provider Info&lt;&#x2F;h3&gt;
&lt;p&gt;Each Wallet Provider will be announced with the following interface &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt;. The values in the &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; MUST be included within the &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; object. The &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; MAY also include extra extensible properties within the object. If a DApp does not recognize the additional properties, it SHOULD ignore them.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;uuid&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; - a globally unique identifier the Wallet Provider that MUST be (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4122&quot;&gt;UUIDv4&lt;&#x2F;a&gt; compliant) to uniquely distinguish different &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt; provider sessions that have matching properties defined below during the lifetime of the page. The cryptographic uniqueness provided by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4122&quot;&gt;UUIDv4&lt;&#x2F;a&gt; guarantees that two independent &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; objects can be separately identified.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; - a human-readable local alias of the Wallet Provider to be displayed to the user on the DApp. (e.g. &lt;code&gt;Example Wallet Extension&lt;&#x2F;code&gt; or &lt;code&gt;Awesome Example Wallet&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;icon&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; - a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3986&quot;&gt;URI&lt;&#x2F;a&gt; pointing to an image. The image SHOULD be a square with 96x96px minimum resolution. See the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6963&#x2F;#images-icons&quot;&gt;Images&#x2F;Icons&lt;&#x2F;a&gt; below for further requirements of this property.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;rdns&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; - The Wallet MUST supply the &lt;code&gt;rdns&lt;&#x2F;code&gt; property which is intended to be a domain name from the Domain Name System in reverse syntax ordering such as &lt;code&gt;com.example.subdomain&lt;&#x2F;code&gt;. It&#x27;s up to the Wallet to determine the domain name they wish to use, but it&#x27;s generally expected the identifier will remain the same throughout the development of the Wallet. It&#x27;s also worth noting that similar to a user agent string in browsers, there are times where the supplied value could be unknown, invalid, incorrect, or attempt to imitate a different Wallet. Therefore, the DApp SHOULD be able to handle these failure cases with minimal degradation to the functionality of the DApp.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Represents the assets needed to display a wallet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  uuid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  icon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  rdns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;h4 id=&quot;images-icons&quot;&gt;Images&#x2F;Icons&lt;&#x2F;h4&gt;
&lt;p&gt;A URI-encoded image was chosen to enable flexibility for multiple protocols for fetching and rendering icons, for example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; svg (data uri)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;data:image&#x2F;svg+xml,&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;svg&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; version=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; xmlns=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; width=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;32px&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; height=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;32px&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; viewBox=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0 0 32 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;circle&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; fill=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;red&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cx=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cy=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;sv&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; png (data uri)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;data:image&#x2F;png&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4&#x2F;&#x2F;8&#x2F;w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;icon&lt;&#x2F;code&gt; string MUST be a data URI as defined in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2397&quot;&gt;RFC-2397&lt;&#x2F;a&gt;. The image SHOULD be a square with 96x96px minimum resolution. The image format is RECOMMENDED to be either lossless or vector based such as PNG, WebP or SVG to make the image easy to render on the DApp. Since SVG images can execute Javascript, applications and libraries MUST render SVG images using the &lt;code&gt;&amp;lt;img&amp;gt;&lt;&#x2F;code&gt; tag to ensure no untrusted Javascript execution can occur.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;rdns&quot;&gt;RDNS&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;strong&gt;&lt;code&gt;rdns&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; (Reverse-DNS) property serves to provide an identifier which DApps can rely on to be stable between sessions. The Reverse Domain Name Notation is chosen to prevent namespace collisions.
The Reverse-DNS convention implies that the value should start with a reversed DNS domain name controlled by the Provider. The domain name should be followed by a subdomain or a product name. Example: &lt;code&gt;com.example.MyBrowserWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;rdns&lt;&#x2F;code&gt; value MUST BE a valid &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc1034&quot;&gt;RFC-1034&lt;&#x2F;a&gt; Domain Name;&lt;&#x2F;li&gt;
&lt;li&gt;The DNS part of the &lt;code&gt;rdns&lt;&#x2F;code&gt; value SHOULD BE an active domain controlled by the Provider;&lt;&#x2F;li&gt;
&lt;li&gt;DApps MAY reject the Providers which do not follow the Reverse-DNS convention correctly;&lt;&#x2F;li&gt;
&lt;li&gt;DApps SHOULD NOT use the &lt;code&gt;rnds&lt;&#x2F;code&gt; value for feature detection as these are self-attested and prone to impersonation or bad incentives without an additional verification mechanism; feature-discovery and verification are both out of scope of this interface specification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;provider-detail&quot;&gt;Provider Detail&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt; is used as a composition interface to announce a Wallet Provider and related metadata about the Wallet Provider. The &lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt; MUST contain an &lt;code&gt;info&lt;&#x2F;code&gt; property of type &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; and a &lt;code&gt;provider&lt;&#x2F;code&gt; property of type &lt;code&gt;EIP1193Provider&lt;&#x2F;code&gt; defined by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderDetail&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  info&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderInfo&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP1193Provider&lt;&#x2F;span&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;h3 id=&quot;window-events&quot;&gt;Window Events&lt;&#x2F;h3&gt;
&lt;p&gt;In order to prevent provider collisions, the DApp and the Wallet are expected to emit an event and instantiate an eventListener to discover the various Wallets. This forms an Event concurrency loop.&lt;&#x2F;p&gt;
&lt;p&gt;Since the DApp code and Wallet code aren&#x27;t guaranteed to run in a particular order, the events are designed to handle such race conditions.&lt;&#x2F;p&gt;
&lt;p&gt;To emit events, both DApps and Wallets MUST use the &lt;code&gt;window.dispatchEvent&lt;&#x2F;code&gt; function to emit events and MUST use the &lt;code&gt;window.addEventListener&lt;&#x2F;code&gt; function to observe events. There are two Event interfaces used for the DApp and Wallet to discover each other.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;announce-and-request-events&quot;&gt;Announce and Request Events&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;EIP6963AnnounceProviderEvent&lt;&#x2F;code&gt; interface MUST be a &lt;code&gt;CustomEvent&lt;&#x2F;code&gt; object with a &lt;code&gt;type&lt;&#x2F;code&gt; property containing a string value of &lt;code&gt;eip6963:announceProvider&lt;&#x2F;code&gt; and a &lt;code&gt;detail&lt;&#x2F;code&gt; property with an object value of type &lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt;. The &lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt; object SHOULD be frozen by calling &lt;code&gt;Object.freeze()&lt;&#x2F;code&gt; on the value of the &lt;code&gt;detail&lt;&#x2F;code&gt; property.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Announce Event dispatched by a Wallet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963AnnounceProviderEvent&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; CustomEvent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:announceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-variable&quot;&gt;  detail&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderDetail&lt;&#x2F;span&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 &lt;code&gt;EIP6963RequestProviderEvent&lt;&#x2F;code&gt; interface MUST be an &lt;code&gt;Event&lt;&#x2F;code&gt; object with a &lt;code&gt;type&lt;&#x2F;code&gt; property containing a string value of &lt;code&gt;eip6963:requestProvider&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Request Event dispatched by a DApp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963RequestProviderEvent&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; Event&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:requestProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Wallet MUST announce the &lt;code&gt;EIP6963AnnounceProviderEvent&lt;&#x2F;code&gt; to the DApp via a &lt;code&gt;window.dispatchEvent()&lt;&#x2F;code&gt; function call. The Wallet MUST add an EventListener to catch an &lt;code&gt;EIP6963RequestProviderEvent&lt;&#x2F;code&gt; dispatched from the DApp. This EventListener MUST use a handler that will re-dispatch an &lt;code&gt;EIP6963AnnounceProviderEvent&lt;&#x2F;code&gt;. This re-announcement by the Wallet is useful for when a Wallet&#x27;s initial Event announcement may have been delayed or fired before the DApp had initialized its EventListener. This allows the various Wallet Providers to react to the DApp without the need to pollute the &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; namespace which can produce non-deterministic wallet behavior such as different wallets connecting each time.&lt;&#x2F;p&gt;
&lt;p&gt;The Wallet dispatches the &lt;code&gt;&quot;eip6963:announceProvider&quot;&lt;&#x2F;code&gt; event with immutable contents and listens to the &lt;code&gt;&quot;eip6963:requestProvider&quot;&lt;&#x2F;code&gt; event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; info&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderInfo&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP1193Provider&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; announceEvent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963AnnounceProviderEvent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CustomEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:announceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;  {&lt;&#x2F;span&gt;&lt;span&gt; detail&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Object&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;freeze&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; info&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Wallet dispatches an announce event which is heard by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the DApp code that had run earlier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dispatchEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;announceEvent&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Wallet listens to the request events which may be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; dispatched later and re-dispatches the `EIP6963AnnounceProviderEvent`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;addEventListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:requestProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dispatchEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;announceEvent&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&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 DApp MUST listen for the &lt;code&gt;EIP6963AnnounceProviderEvent&lt;&#x2F;code&gt; dispatched by the Wallet via a &lt;code&gt;window.addEventListener()&lt;&#x2F;code&gt; method and MUST NOT remove the Event Listener for the lifetime of the page so that the DApp can continue to handle Events beyond the initial page load interaction. The DApp MUST dispatch the &lt;code&gt;EIP6963RequestProviderEvent&lt;&#x2F;code&gt; via a &lt;code&gt;window.dispatchEvent()&lt;&#x2F;code&gt; function call after the &lt;code&gt;EIP6963AnnounceProviderEvent&lt;&#x2F;code&gt; handler has been initialized.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The DApp listens to announced providers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;addEventListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:announceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963AnnounceProviderEvent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The DApp dispatches a request event which will be heard by &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Wallets&amp;#39; code that had run earlier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dispatchEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Event&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:requestProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&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 DApp MAY elect to persist various &lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt; objects contained in the  announcement events sent by multiple wallets. Thus, if the user wishes to utilize a different Wallet over time, the user can express this within the DApp&#x27;s interface and the DApp can immediately elect to send transactions to that new Wallet. Otherwise, the DApp MAY re-initiate the wallet discovery flow via dispatching a new &lt;code&gt;EIP6963RequestProviderEvent&lt;&#x2F;code&gt;, potentially discovering a different set of wallets.&lt;&#x2F;p&gt;
&lt;p&gt;The described orchestration of events guarantees that the DApp is able to discover the Wallet, regardless of which code executes first, the Wallet code or the DApp code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The previous proposal introduced mechanisms that relied on a single, mutable window object that could be overwritten by multiple parties. We opted for an event-based approach to avoid the race conditions, the namespace collisions, and the potential for &quot;pollution&quot; attacks on a shared mutable object; the event-based orchestration creates a bidirectional communication channel between wallet and dapp that can be re-orchestrated over time.&lt;&#x2F;p&gt;
&lt;p&gt;To follow the Javascript event name conventions, the names are written in present tense and are prefixed with the number of this document (&lt;code&gt;EIP6963&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interfaces&quot;&gt;Interfaces&lt;&#x2F;h3&gt;
&lt;p&gt;Standardizing an interface for provider information (&lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt;) allows a DApp to determine all information necessary to populate a user-friendly wallet selection modal. This is particularly useful for DApps that rely on libraries such as Web3Modal, RainbowKit, Web3-Onboard, or ConnectKit to programmatically generate such selection modals.&lt;&#x2F;p&gt;
&lt;p&gt;Regarding the announced provider interface (&lt;code&gt;EIP6963ProviderDetail&lt;&#x2F;code&gt;), it was important to leave the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt; provider interface untouched for backwards compatibility; this allows conformant DApps to interface with wallets conforming to either, and for Wallets conformant to this spec to still inject &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt; providers for legacy DApps. Note that a legacy dapp or a DApp conformant with this spec connecting to a legacy wallet cannot guarantee the correct wallet will be selected if multiple are present.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP doesn&#x27;t require supplanting &lt;code&gt;window.ethereum&lt;&#x2F;code&gt;, so it doesn&#x27;t directly break existing applications that cannot update to this method of Wallet discovery. However, it is RECOMMENDED DApps implement this EIP to ensure discovery of multiple Wallet Providers and SHOULD disable &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; usage except as a fail-over when discovery fails. Similarly, Wallets SHOULD keep compatibility of &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; to ensure backwards compatibility for DApps that have not implemented this EIP. In order to prevent the previous issues of namespace collisions, it&#x27;s also RECOMMENDED that wallets inject their provider object under a wallet specific namespace then proxy the object into the &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; namespace.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;wallet-provider&quot;&gt;Wallet Provider&lt;&#x2F;h3&gt;
&lt;p&gt;Here is a reference implementation for an injected script by a Wallet Provider to support this new interface in parallel with the existing pattern.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onPageLoad&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP1193Provider&lt;&#x2F;span&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 class=&quot;z-variable z-other&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; announceProvider&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; info&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;      uuid&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;350670db-19fa-4704-a166-e52e178b59d2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;      name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Example Wallet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;      icon&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;data:image&#x2F;svg+xml,&amp;lt;svg xmlns=&amp;#39;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&amp;#39;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;      rdns&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;com.example.wallet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dispatchEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CustomEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:announceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        detail&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Object&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;freeze&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; info&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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&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&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&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 class=&quot;z-variable z-other&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;addEventListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:requestProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963RequestProviderEvent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-entity z-name&quot;&gt;      announceProvider&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-entity z-name&quot;&gt;  announceProvider&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;dapp-implementation&quot;&gt;DApp implementation&lt;&#x2F;h3&gt;
&lt;p&gt;Here is a reference implementation for a DApp to display and track multiple Wallet Providers that are injected by browser extensions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; providers&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963ProviderDetail&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onPageLoad&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;addEventListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:announceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP6963AnnounceProviderEvent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;      providers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;event&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;detail&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-variable z-other&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dispatchEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Event&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eip6963:requestProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;eip-1193-security-considerations&quot;&gt;EIP-1193 Security considerations&lt;&#x2F;h3&gt;
&lt;p&gt;The security considerations of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt; apply to this EIP. Implementers are expected to consider and follow the guidance of the providers they&#x27;re utilizing as well.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prototype-pollution-of-wallet-provider-objects&quot;&gt;Prototype Pollution of Wallet Provider objects&lt;&#x2F;h3&gt;
&lt;p&gt;Browser extensions, and therefore Wallet extensions, are able to modify the contents of the page and the Provider object by design. The provider objects of various Wallets are considered a highly trusted interface to communicate transaction data. In order to prevent the page or various other extensions from modifying the interaction between the DApp and the Wallet in an unexpected way, the best practice is to &quot;freeze&quot; the provider discovery object by utilizing &lt;code&gt;object.freeze()&lt;&#x2F;code&gt; on the  &lt;code&gt;EIP1193Provider&lt;&#x2F;code&gt; object before the wallet dispatches it in the &lt;code&gt;eip6963:announceProvider&lt;&#x2F;code&gt; Event. However, there are difficulties that can occur around web compatibility where pages need to monkey patch the object. In scenarios like this there&#x27;s a tradeoff that needs to be made between security and web compatibility that Wallet implementers are expected to consider.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-imitation-and-manipulation&quot;&gt;Wallet Imitation and Manipulation&lt;&#x2F;h3&gt;
&lt;p&gt;Similarly so, DApps are expected to actively detect for misbehavior of properties or functions being modified in order to tamper with or modify other wallets. One way this can be easily achieved is to look for when the &lt;code&gt;uuid&lt;&#x2F;code&gt; property within two &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; objects match. DApps and DApp discovery libraries are expected to consider other potential methods that the &lt;code&gt;EIP6963ProviderInfo&lt;&#x2F;code&gt; objects are being tampered with and consider additional mitigation techniques to prevent this as well in order to protect the user.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prevent-svg-javascript-execution&quot;&gt;Prevent SVG Javascript Execution&lt;&#x2F;h3&gt;
&lt;p&gt;The use of SVG images introduces a cross-site scripting risk as they can include JavaScript code. This Javascript executes within the context of the page and can therefore modify the page or the contents of the page. So when considering the experience of rendering the icons, DApps need to take into consideration how they&#x27;ll approach handling these concerns in order to prevent an image being used as an obfuscation technique to hide malicious modifications to the page or to other wallets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prevent-wallet-fingerprinting&quot;&gt;Prevent Wallet Fingerprinting&lt;&#x2F;h3&gt;
&lt;p&gt;One advantage to the concurrency Event loop utilized by this design is that it operates in a manner where either the DApp or the Wallet can initiate the flow to announce a provider. For this reason, Wallet implementers can now consider whether or not they wish to announce themselves to all pages or attempt alternative means in order to reduce the ability for a user to be fingerprinted by the injection of the &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; object. Some examples, of alternative flows to consider would be to wait to inject the provider object until the DApp has announced the &lt;code&gt;eip6963:requestProvider&lt;&#x2F;code&gt;. At that point, the wallet can initiate a UI consent flow to ask the user if they would like to share their wallet address. This allows for the Wallet to enable the option of a &quot;private connect&quot; feature. However, if this approach is taken, Wallets must also consider how they intend to support backwards compatibility with a DApp that does not support this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Network Upgrade Activation Triggers</title>
        <published>2023-04-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6953/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6666-network-upgrade-activation-triggers/14047" />
        

        <id>https://wg-eips.ritovision.com/6953/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        

        
        <category
            term="tag:eip:6953"
            label="EIP-6953" />
        

        
        

        
        <summary type="html">Exhaustive list of network upgrade activation mechanisms</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6953/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP outlines the various network upgrade activation triggers used on Ethereum over time, from the proof-of-work era to the first post-merge network upgrade, Shanghai&#x2F;Capella, across both the execution and consensus layers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP aims to provide users and developers with a single source of truth for understanding the various upgrade activation patterns used throughout Ethereum&#x27;s history. It does not aim to be a comprehensive, ongoing record, of upgrades and their activations mechanism. Readers should assume that future upgrades use the mechanism described in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6953&#x2F;#post-merge-upgrades&quot;&gt;Post Merge Upgrades&lt;&#x2F;a&gt; section, unless this EIP is superseded by another one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;proof-of-work-network-upgrades&quot;&gt;Proof-of-Work Network Upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;During the proof-of-work era, network upgrades on Ethereum were triggered based on specific block numbers. The following upgrades followed this pattern:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Upgrade Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Block Number&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Frontier&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Frontier Thawing&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;200000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Homestead&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1150000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DAO Fork&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1920000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tangerine Whistle&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2463000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Spurious Dragon&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2675000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Byzantium&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;4370000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Constantinople&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;7280000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Petersburg&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;7280000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Istanbul&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;9069000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Muir Glacier&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;9200000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Berlin&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;12244000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;London&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;12965000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Arrow Glacier&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;13773000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Gray Glacier&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;15050000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;beacon-chain-launch&quot;&gt;Beacon Chain Launch&lt;&#x2F;h3&gt;
&lt;p&gt;The Beacon Chain was launched following a set of conditions detailed in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;&quot;&gt;EIP-2982&lt;&#x2F;a&gt;. The launch was activated once all the following conditions were met:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The Beacon Chain deposit contract received at least &lt;code&gt;524288&lt;&#x2F;code&gt; ETH from &lt;code&gt;16384&lt;&#x2F;code&gt; validators.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;MIN_GENESIS_TIME&lt;&#x2F;code&gt; timestamp of &lt;code&gt;1606824000&lt;&#x2F;code&gt; (Dec 1, 2020) had been exceeded.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;GENESIS_DELAY&lt;&#x2F;code&gt; of &lt;code&gt;604800&lt;&#x2F;code&gt; seconds had passed since the minimum validator count was exceeded.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;beacon-chain-upgrades&quot;&gt;Beacon Chain Upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;Beacon Chain upgrades are activated at specific epochs. The following upgrades followed this pattern:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Upgrade Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Altair&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;74240&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Bellatrix&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;144896&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;the-merge-paris-upgrade&quot;&gt;The Merge: Paris Upgrade&lt;&#x2F;h3&gt;
&lt;p&gt;The Paris upgrade, the execution layer portion of &quot;The Merge,&quot; was triggered by a proof-of-work Total Difficulty value of &lt;code&gt;58750000000000000000000&lt;&#x2F;code&gt;, as specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt;. Note that the activation of the Bellatrix upgrade on the Beacon Chain was a pre-requisite for the Paris upgrade to successfully activate on the proof-of-work chain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;post-merge-upgrades&quot;&gt;Post-Merge Upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;After The Merge, network upgrades are triggered at an epoch on the consensus layer (CL), which ideally maps to an historical roots accumulator boundary (i.e., a multiple of 8192 slots). The epoch&#x27;s corresponding timestamp, rather than a block number, is then used on the execution layer (EL) as the activation trigger. The following upgrades followed this pattern:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Upgrade Name&lt;&#x2F;th&gt;&lt;th&gt;Activation Epoch&lt;&#x2F;th&gt;&lt;th&gt;Activation Timestamp&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Capella  (CL)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;194048&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Shanghai (EL)&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1681338455&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Note that epoch &lt;code&gt;194048&lt;&#x2F;code&gt; happened at timestamp &lt;code&gt;1681338455&lt;&#x2F;code&gt;. In other words, the upgrades activated simultaneously on both the execution and consensus layers, even though they each used a different constant to trigger it.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the use of timestamps on the execution layer resulted in changes to how nodes&#x27; &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; and &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; values are calculated. These are described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6122&#x2F;&quot;&gt;EIP-6122&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;blocks-and-epochs&quot;&gt;Blocks and Epochs&lt;&#x2F;h3&gt;
&lt;p&gt;Blocks and epochs serve as natural trigger points for upgrades, as they represent the levels at which state transitions occur on Ethereum.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;terminal-total-difficulty&quot;&gt;Terminal Total Difficulty&lt;&#x2F;h3&gt;
&lt;p&gt;For the Terminal Total Difficulty mechanism, the rationale can be found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;timestamps&quot;&gt;Timestamps&lt;&#x2F;h3&gt;
&lt;p&gt;Due to the possibility of missed slots on the Beacon Chain, the execution layer cannot rely solely on block numbers to trigger upgrades in sync with the consensus layer.&lt;&#x2F;p&gt;
&lt;p&gt;Timestamps are guaranteed to map to a specific epoch, and in their Unix representation, timestamps will always be greater than the block numbers previously used. This allows for a reliable method to trigger upgrades on the execution layer post-merge, while also ensuring that a post-merge upgrade based on a timestamp can never use a value that is considered lower than the last block-triggered upgrade.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Minimal Multi-Token Interface</title>
        <published>2023-04-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>JT Riley</name><uri>https://github.com/jtriley2p</uri>
	</author>
	
	<author>
		<name>Dillon</name><uri>https://github.com/d1ll0n</uri>
	</author>
	
	<author>
		<name>Sara</name><uri>https://github.com/snreynolds</uri>
	</author>
	
	<author>
		<name>Vectorized</name><uri>https://github.com/Vectorized</uri>
	</author>
	
	<author>
		<name>Neodaoist</name><uri>https://github.com/neodaoist</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6909/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-6909-multi-token-standard/13891" />
        

        <id>https://wg-eips.ritovision.com/6909/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6909"
            label="ERC-6909" />
        

        
        

        
        <summary type="html">A minimal specification for managing multiple tokens by their id in a single contract.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6909/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following specifies a multi-token contract as a simplified alternative to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; Multi-Token Standard. In contrast to ERC-1155, callbacks and batching have been removed from the interface and the permission system is a hybrid operator-approval scheme for granular and scalable permissions. Functionally, the interface has been reduced to the bare minimum required to manage multiple tokens under the same contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The ERC-1155 standard includes unnecessary features such as requiring recipient accounts with code to implement callbacks returning specific values and batch-calls in the specification. In addition, the single operator permission scheme grants unlimited allowance on every token ID in the contract. Backwards compatibility is deliberately removed only where necessary. Additional features such as batch calls, increase and decrease allowance methods, and other user experience improvements are deliberately omitted in the specification to minimize the required external interface.&lt;&#x2F;p&gt;
&lt;p&gt;According to ERC-1155, callbacks are required for each transfer and batch transfer to contract accounts. This requires potentially unnecessary external calls to the recipient when the recipient account is a contract account. While this behavior may be desirable in some cases, there is no option to opt-out of this behavior, as is the case for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; having both &lt;code&gt;transferFrom&lt;&#x2F;code&gt; and &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;. In addition to runtime performance of the token contract itself, it also impacts the runtime performance and codesize of recipient contract accounts, requiring multiple callback functions and return values to receive the tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Batching transfers, while useful, are excluded from this standard to allow for opinionated batch transfer operations on different implementations. For example, a different ABI encoding may provide different benefits in different environments such as calldata size optimization for rollups with calldata storage commitments or runtime performance for environments with expensive gas fees.&lt;&#x2F;p&gt;
&lt;p&gt;A hybrid allowance-operator permission scheme enables granular yet scalable controls on token approvals. Allowances enable an external account to transfer tokens of a single token ID on a user&#x27;s behalf w by their ID while operators are granted full transfer permission for all token IDs for the user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Every &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6909&#x2F;&quot;&gt;ERC-6909&lt;&#x2F;a&gt; compliant contract must implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface in addition to the following interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;infinite: The maximum value for a uint256 (&lt;code&gt;2 ** 256 - 1&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;caller: The caller of the current context (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;spender: An account that transfers tokens on behalf of another account.&lt;&#x2F;li&gt;
&lt;li&gt;operator: An account that has unlimited transfer permissions on all token ids for another account.&lt;&#x2F;li&gt;
&lt;li&gt;mint: The creation of an amount of tokens. This MAY happen in a mint method or as a transfer from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;burn: The removal an amount of tokens. This MAY happen in a burn method or as a transfer to the zero address.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;balanceof&quot;&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The total &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; that an &lt;code&gt;owner&lt;&#x2F;code&gt; owns.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;alanceOf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowance&quot;&gt;&lt;code&gt;allowance&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The total &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; that a &lt;code&gt;spender&lt;&#x2F;code&gt; is permitted to transfer on behalf of an &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;llowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;isoperator&quot;&gt;&lt;code&gt;isOperator&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Returns &lt;code&gt;true&lt;&#x2F;code&gt; if the &lt;code&gt;spender&lt;&#x2F;code&gt; is approved as an operator for an &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sOperator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tatus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transfer&quot;&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Transfers an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; from the caller to the &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert when the caller&#x27;s balance for the token &lt;code&gt;id&lt;&#x2F;code&gt; is insufficient.&lt;&#x2F;p&gt;
&lt;p&gt;MUST log the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return True.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ransfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uccess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transferfrom&quot;&gt;&lt;code&gt;transferFrom&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Transfers an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; from a &lt;code&gt;sender&lt;&#x2F;code&gt; to a &lt;code&gt;receiver&lt;&#x2F;code&gt; by the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert when the caller is neither the &lt;code&gt;sender&lt;&#x2F;code&gt; nor an operator for the &lt;code&gt;sender&lt;&#x2F;code&gt; and the caller&#x27;s allowance for the token &lt;code&gt;id&lt;&#x2F;code&gt; for the &lt;code&gt;sender&lt;&#x2F;code&gt; is insufficient.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert when the &lt;code&gt;sender&lt;&#x2F;code&gt;&#x27;s balance for the token id is insufficient.&lt;&#x2F;p&gt;
&lt;p&gt;MUST log the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST decrease the caller&#x27;s &lt;code&gt;allowance&lt;&#x2F;code&gt; by the same &lt;code&gt;amount&lt;&#x2F;code&gt; of the &lt;code&gt;sender&lt;&#x2F;code&gt;&#x27;s balance decrease if the caller is not an operator for the &lt;code&gt;sender&lt;&#x2F;code&gt; and the caller&#x27;s &lt;code&gt;allowance&lt;&#x2F;code&gt; is not infinite.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD NOT decrease the caller&#x27;s &lt;code&gt;allowance&lt;&#x2F;code&gt; for the token &lt;code&gt;id&lt;&#x2F;code&gt; for the &lt;code&gt;sender&lt;&#x2F;code&gt; if the &lt;code&gt;allowance&lt;&#x2F;code&gt; is infinite.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD NOT decrease the caller&#x27;s &lt;code&gt;allowance&lt;&#x2F;code&gt; for the token &lt;code&gt;id&lt;&#x2F;code&gt; for the &lt;code&gt;sender&lt;&#x2F;code&gt; if the caller is an operator or the &lt;code&gt;sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return True.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ransferFrom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uccess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;approve&quot;&gt;&lt;code&gt;approve&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Approves an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; that a &lt;code&gt;spender&lt;&#x2F;code&gt; is permitted to transfer on behalf of the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST set the &lt;code&gt;allowance&lt;&#x2F;code&gt; of the &lt;code&gt;spender&lt;&#x2F;code&gt; of the token &lt;code&gt;id&lt;&#x2F;code&gt; for the caller to the &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST log the &lt;code&gt;Approval&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return True.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pprove&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uccess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;setoperator&quot;&gt;&lt;code&gt;setOperator&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Grants or revokes unlimited transfer permissions for a &lt;code&gt;spender&lt;&#x2F;code&gt; for any token &lt;code&gt;id&lt;&#x2F;code&gt; on behalf of the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST set the operator status to the &lt;code&gt;approved&lt;&#x2F;code&gt; value.&lt;&#x2F;p&gt;
&lt;p&gt;MUST log the &lt;code&gt;OperatorSet&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return True.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;etOperator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uccess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;transfer-1&quot;&gt;&lt;code&gt;Transfer&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;caller&lt;&#x2F;code&gt; initiates a transfer of an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; from a &lt;code&gt;sender&lt;&#x2F;code&gt; to a &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged when an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; is transferred from one account to another.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged with the &lt;code&gt;sender&lt;&#x2F;code&gt; address as the zero address when an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; is minted.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged with the &lt;code&gt;receiver&lt;&#x2F;code&gt; address as the zero address when an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; is burned.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ransfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;aller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;operatorset&quot;&gt;&lt;code&gt;OperatorSet&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;owner&lt;&#x2F;code&gt; has set the &lt;code&gt;approved&lt;&#x2F;code&gt; status to a &lt;code&gt;spender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged when the operator status is set.&lt;&#x2F;p&gt;
&lt;p&gt;MAY be logged when the operator status is set to the same status it was before the current call.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; O&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;peratorSet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;approval&quot;&gt;&lt;code&gt;Approval&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;owner&lt;&#x2F;code&gt; has approved a &lt;code&gt;spender&lt;&#x2F;code&gt; to transfer an &lt;code&gt;amount&lt;&#x2F;code&gt; of a token &lt;code&gt;id&lt;&#x2F;code&gt; to be transferred on the owner&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be logged when the &lt;code&gt;allowance&lt;&#x2F;code&gt; is set by an &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pproval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;interface-id&quot;&gt;Interface ID&lt;&#x2F;h3&gt;
&lt;p&gt;The interface ID is &lt;code&gt;0x0f632fb3&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;metadata-extension&quot;&gt;Metadata Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;methods-1&quot;&gt;Methods&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;name&quot;&gt;name&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;name&lt;&#x2F;code&gt; for a token &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ame&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ame&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;symbol&quot;&gt;symbol&lt;&#x2F;h5&gt;
&lt;p&gt;The ticker &lt;code&gt;symbol&lt;&#x2F;code&gt; for a token &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ymbol&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ymbol&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;decimals&quot;&gt;decimals&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;amount&lt;&#x2F;code&gt; of decimals for a token &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ecimals&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;content-uri-extension&quot;&gt;Content URI Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;methods-2&quot;&gt;Methods&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;contracturi&quot;&gt;contractURI&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;URI&lt;&#x2F;code&gt; for the contract.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontractURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ri&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;tokenuri&quot;&gt;tokenURI&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;URI&lt;&#x2F;code&gt; for a token &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MAY revert if the token &lt;code&gt;id&lt;&#x2F;code&gt; does not exist.&lt;&#x2F;p&gt;
&lt;p&gt;MUST replace occurrences of &lt;code&gt;{id}&lt;&#x2F;code&gt; in the returned URI string by the client.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;okenURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ri&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;metadata-structure&quot;&gt;Metadata Structure&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;contract-uri&quot;&gt;Contract URI&lt;&#x2F;h5&gt;
&lt;p&gt;JSON Schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The name of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The description of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image_url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The URL of the image representing the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;banner_image_url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The URL of the banner image of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;external_link&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The external link of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;editors&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;An Ethereum address representing an authorized editor of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;An array of Ethereum addresses representing editors (authorized editors) of the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;animation_url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;An animation URL for the contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;JSON Example (Minimal):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Example Contract Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;token-uri&quot;&gt;Token URI&lt;&#x2F;h5&gt;
&lt;p&gt;MUST replace occurrences of &lt;code&gt;{id}&lt;&#x2F;code&gt; in the returned URI string by the client.&lt;&#x2F;p&gt;
&lt;p&gt;JSON Schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to an image resource.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;animation_url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;An animation URL for the token.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;JSON Example (Minimal):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Example Token Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Example Token Description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;exampleurl&#x2F;{id}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;h3 id=&quot;token-supply-extension&quot;&gt;Token Supply Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;methods-3&quot;&gt;Methods&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;totalsupply&quot;&gt;totalSupply&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;totalSupply&lt;&#x2F;code&gt; for a token &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;otalSupply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;upply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;granular-approvals&quot;&gt;Granular Approvals&lt;&#x2F;h3&gt;
&lt;p&gt;While the &quot;operator model&quot; from the ERC-1155 standard allows an account to set another account as an operator, giving full permissions to transfer any amount of any token id on behalf of the owner, this may not always be the desired permission scheme. The &quot;allowance model&quot; from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; allows an account to set an explicit amount of the token that another account can spend on the owner&#x27;s behalf. This standard requires both be implemented, with the only modification being to the &quot;allowance model&quot; where the token id must be specified as well. This allows an account to grant specific approvals to specific token ids, infinite approvals to specific token ids, or infinite approvals to all token ids.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removal-of-batching&quot;&gt;Removal of Batching&lt;&#x2F;h3&gt;
&lt;p&gt;While batching operations is useful, its place should not be in the standard itself, but rather on a case-by-case basis. This allows for different tradeoffs to be made in terms of calldata layout, which may be especially useful for specific applications such as roll-ups that commit calldata to global storage.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removal-of-required-callbacks&quot;&gt;Removal of Required Callbacks&lt;&#x2F;h3&gt;
&lt;p&gt;Requiring callbacks unnecessarily encumbers implementors that either have no particular use case for callbacks or prefer a bespoke callback mechanism. Minimization of such requirements saves contract size, gas efficiency and complexity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removal-of-safe-naming&quot;&gt;Removal of &quot;Safe&quot; Naming&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;safeTransfer&lt;&#x2F;code&gt; and &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; naming conventions are misleading, especially in the context of the ERC-1155 and ERC-721 standards, as they require external calls to receiver accounts with code, passing the execution flow to an arbitrary contract, provided the receiver contract returns a specific value. The combination of removing mandatory callbacks and removing the word &quot;safe&quot; from all method names improves the safety of the control flow by default.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is not backwards compatible with ERC-1155 as some methods are removed. However, wrappers can be implemented for the ERC-20, ERC-721, and ERC-1155 standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC6909 Multi-Token Reference Implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @author&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; jtriley.eth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6909&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Thrown when owner balance for id is insufficient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Thrown when spender allowance for id is insufficient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InsufficientPermission&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when a transfer occurs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; caller&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an operator is set.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval status.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OperatorSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when an approval occurs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner balance of an id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; id &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balanceOf&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Spender allowance of an id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; id &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks if a spender is approved by an owner as an operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; isOperator&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers an amount of an id from the caller to a receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;receiver&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers an amount of an id from a sender to a receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the receiver.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            uint256&lt;&#x2F;span&gt;&lt;span&gt; senderAllowance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;senderAllowance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InsufficientPermission&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;senderAllowance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max&lt;&#x2F;span&gt;&lt;span&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&gt;                allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senderAllowance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;receiver&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approves an amount of an id to a spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;        allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;spender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets or removes a spender as an operator for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The approval status.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;        isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;spender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OperatorSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; approved&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks if a contract implements an interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface identifier, as specified in ERC-165.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the contract implements `interfaceId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supported&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x0f632fb3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WARNING: important safety checks should precede calls to this method.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;receiver&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; WARNING: important safety checks should precede calls to this method.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      balanceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;approvals-and-operators&quot;&gt;Approvals and Operators&lt;&#x2F;h3&gt;
&lt;p&gt;The specification includes two token transfer permission systems, the &quot;allowance&quot; and &quot;operator&quot;
models. There are two security considerations in regards to delegating permission to transfer.&lt;&#x2F;p&gt;
&lt;p&gt;The first consideration is consistent with all delegated permission models. Any account with an allowance may transfer the full allowance for any reason at any time until the allowance is revoked. Any account with operator permissions may transfer any amount of any token id on behalf of the owner until the operator permission is revoked.&lt;&#x2F;p&gt;
&lt;p&gt;The second consideration is unique to systems with both delegated permission models. If an account has both operator permissions and an insufficient allowance for a given transfer, performing the allowance check before the operator check would result in a revert while performing the operator check before the allowance check would not. The specification intentionally leaves this unconstrained for cases where implementors may track allowances despite the operator status. Nonetheless, this is a notable consideration.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6909OperatorPrecedence&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -- snip --&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if `isOperator` first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;insufficient allowance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -- snip --&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6909AllowancePrecedence&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -- snip --&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if allowance is sufficient first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;isOperator&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;insufficient allowance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERROR: when allowance is insufficient, this panics due to arithmetic underflow, regardless of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; whether the caller has operator permissions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    allowance&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; -- snip&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;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Automatically Reset Testnet</title>
        <published>2023-04-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mário Havel</name><uri>https://github.com/taxmeifyoucan</uri>
	</author>
	
	<author>
		<name>pk910</name><uri>https://github.com/pk910</uri>
	</author>
	
	<author>
		<name>Rémy Roy</name><uri>https://github.com/remyroy</uri>
	</author>
	
	<author>
		<name>Holly Atkinson</name><uri>https://github.com/atkinsonholly</uri>
	</author>
	
	<author>
		<name>Tereza Burianova</name><uri>https://github.com/T-ess</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6916/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/automatically-reset-testnet/15825" />
        

        <id>https://wg-eips.ritovision.com/6916/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6916"
            label="EIP-6916" />
        

        
        

        
        <summary type="html">A testnet network that periodically rolls back to genesis</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6916/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a specification for an automatically reset testnet, a novel approach to testnets that can be implemented within Ethereum clients. It enables a single testing infrastructure consisting of ephemeral networks with deterministic parameters. Each network iteration is created by a specified function which deterministically generates genesis states.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A testnet which automatically resets can provide an alternative environment for short-term testing of applications, validators and also breaking changes in client implementations. It avoids issues of long running testnets which suffer from state bloat, lack of testnet funds or consensus issues. Periodically resetting the network back to genesis cleans the validator set and returns funds back to faucets while keeping the network reasonably small for easy bootstrapping.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The testnet is set to always reset after a predefined time period. The reset means the generation of the next genesis, discarding the old one and starting a new network. This is possible by introducing functions for the genesis generation and the client reset.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;genesis&quot;&gt;Genesis&lt;&#x2F;h3&gt;
&lt;p&gt;To connect to the current instance of the network, the client must implement the genesis function. This function defines how the client stores information about the testnet and generates the current genesis. With each reset, the network starts from a new genesis which needs to be built based on given parameters and correspond in EL and CL clients.&lt;&#x2F;p&gt;
&lt;p&gt;The network always starts from a genesis which is deterministically created based on the original one - this very first genesis is hardcoded and we can call it &lt;code&gt;genesis 0&lt;&#x2F;code&gt;. Terminal time, the expiration of each genesis, is the addition of the start time of that genesis &lt;code&gt;MIN_GENESIS_TIME&lt;&#x2F;code&gt; and the testnet lifetime &lt;code&gt;period&lt;&#x2F;code&gt;, where &lt;code&gt;period&lt;&#x2F;code&gt; is a constant defining the length of time a single ephemeral network runs. Therefore, once the current slot timestamp reaches the terminal time of the ephemeral network, it has to switch to a new genesis. The main changes in each new genesis iteration are chainId, genesis time and the withdrawal credentials of the first validator.&lt;&#x2F;p&gt;
&lt;p&gt;Clients shall include a hardcoded &lt;code&gt;genesis 0&lt;&#x2F;code&gt; parameters, much like other networks predefined in clients. However, this genesis shall be used directly, only at the very beginning of the testnet&#x27;s existence, in its first iteration where &lt;code&gt;i&lt;&#x2F;code&gt; equals &lt;code&gt;0&lt;&#x2F;code&gt;. Later on, with iteration &lt;code&gt;i&lt;&#x2F;code&gt; equal to &lt;code&gt;1&lt;&#x2F;code&gt; and above, the client does not initialize this genesis but uses it to derive the current one. When &lt;code&gt;i&amp;gt;0&lt;&#x2F;code&gt;, given a known &lt;code&gt;period&lt;&#x2F;code&gt; and current slot timestamp, the client always calculates the number of lifecycle iterations from &lt;code&gt;genesis 0&lt;&#x2F;code&gt; and creates a new genesis with the latest parameters.&lt;&#x2F;p&gt;
&lt;p&gt;When the client starts with the option of an ephemeral testnet, it checks whether a genesis for the network is present. If it doesn&#x27;t exist or the current slot timestamp is older than &lt;code&gt;current_genesis.genesis_time + period&lt;&#x2F;code&gt;, it triggers the generation of a new genesis. This new genesis, derived from &lt;code&gt;genesis 0&lt;&#x2F;code&gt;, will be written to the database and used to run the current network.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;execution-client&quot;&gt;Execution client&lt;&#x2F;h4&gt;
&lt;p&gt;The EL client includes the hardcoded &lt;code&gt;genesis 0&lt;&#x2F;code&gt; serving as a preimage for generating the current one. Iteration of variables is done as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Number of iterations:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;i&lt;&#x2F;code&gt; = &lt;code&gt;int((current_slot_timestamp&lt;&#x2F;code&gt; - &lt;code&gt;genesis_0.genesis_time) &#x2F; period)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Genesis time of current genesis:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;current_genesis.genesis_time&lt;&#x2F;code&gt; = &lt;code&gt;period&lt;&#x2F;code&gt; * &lt;code&gt;i&lt;&#x2F;code&gt; + &lt;code&gt;genesis_0.genesis_time&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Current EL ChainId:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;chainId&lt;&#x2F;code&gt; = &lt;code&gt;genesis_0.chainId&lt;&#x2F;code&gt; + &lt;code&gt;i&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;consensus-client&quot;&gt;Consensus client&lt;&#x2F;h4&gt;
&lt;p&gt;Genesis generation in the CL client includes config with iterated values, similarly to EL, but also requires the updated genesis state. The state in SSZ format can be either generated by the client or downloaded from an external source. It includes validators with deposits ready to launch a merged network with the validator set created by trusted entities within the community.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;MIN_GENESIS_TIME&lt;&#x2F;code&gt; is set to the latest genesis time and defines when the current period starts. It is recommended to add a small &lt;code&gt;GENESIS_DELAY&lt;&#x2F;code&gt;, for example 15 minutes, to avoid issues while infrastructure is restarting with the new genesis.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure a successful reset, &lt;code&gt;ForkDigest&lt;&#x2F;code&gt; needs to be unique for each iteration. In order to keep the &lt;code&gt;ForkVersions&lt;&#x2F;code&gt; of the network static for better tooling support, the withdrawal credentials of the first validator in the validator set need to be overridden by a calculated value.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;genesis.validators[0].withdrawal_credentials&lt;&#x2F;code&gt; = &lt;code&gt;0x0100000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt; + &lt;code&gt;i&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;genesis.genesis_validators_root&lt;&#x2F;code&gt; =  &lt;code&gt;hash_tree_root(genesis.validators)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The update of &lt;code&gt;genesis.validators[0]&lt;&#x2F;code&gt; changes the state, therefore, clients have to be able to generate or download the latest genesis state. Generating the genesis ssz is not considered a standard client feature and adding it enables to trustlessly create the latest genesis state at the price of certain complexity. An alternative solution is to obtain it from a third party, either by downloading the ssz file from a server or using the checkpoint sync feature with an endpoint serving the genesis state. This became an accepted practice with Holešky testnet and existing features of checkpoint sync can be used for obtaining genesis states for automatically reset testnets. It also allows maintainers to update the genesis validator set without requiring new client releases. The full implementation of the recommended practice for obtaining the latest CL state should behave as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;When the testnet flag is provided and client supports checkpoint sync of genesis, automatically use the hardcoded checkpoint endpoint to download the latest genesis state using the checkpoint sync feature
&lt;ul&gt;
&lt;li&gt;If user provides a custom checkpoint sync flag, override the default option and use the endpoint provided by user&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Include a backup download option pointing to an url with the latest testnet release, a publicly distributed ssz file, and trigger this option if the checkpoint state sync fails or make it the default if client doesn&#x27;t support genesis checkpoint sync&lt;&#x2F;li&gt;
&lt;li&gt;If the client includes a feature for generating the genesis or some of its parameters, use it to verify parameters in the downloaded state and issue an error if values or checksum don&#x27;t correspond&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It&#x27;s important to note that &lt;code&gt;genesis_validators_root&lt;&#x2F;code&gt; is normally predefined in the client but in this case it&#x27;s not known in advance which can potentially break certain architectures. For example light clients which are relying on hardcoded &lt;code&gt;genesis_validators_root&lt;&#x2F;code&gt; won&#x27;t work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reset&quot;&gt;Reset&lt;&#x2F;h3&gt;
&lt;p&gt;The reset function defines an automatic process of throwing away the old data and starting with a new genesis. It depends on the previously defined function for genesis generation which the client must implement in order to be able to automatically follow the latest network iteration.&lt;&#x2F;p&gt;
&lt;p&gt;For the reset function, we can introduce the &lt;code&gt;terminal_timestamp&lt;&#x2F;code&gt; value which defines the network expiry time of an iteration. It can be the same as the genesis time of the next iteration (without the genesis delay) or can be calculated simply as &lt;code&gt;terminal_timestamp = current_genesis.genesis_time + period&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When the network reaches a slot with a timestamp &lt;code&gt;&amp;gt;= terminal_timestamp&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Client stops accepting&#x2F;creating new blocks
&lt;ul&gt;
&lt;li&gt;Shutdown client services running the network, e.g. p2p communication, beacon service, execution environment&lt;&#x2F;li&gt;
&lt;li&gt;This feature should be implemented alongside Genesis even without further reset functions just to create a basic support which is always safe from forking&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Client calls a function which discards the current genesis, all chain or beacon data
&lt;ul&gt;
&lt;li&gt;Clients already include db tools including for purging the database which could be used here&lt;&#x2F;li&gt;
&lt;li&gt;It might be beneficial to include an additional flag, e.g. &lt;code&gt;--retain-ephemeral-data&lt;&#x2F;code&gt;, which would first export the existing data in a standard format before removing the database&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Client triggers the Genesis function (as defined above):
&lt;ul&gt;
&lt;li&gt;Behaves like a regular client startup when genesis is not present&lt;&#x2F;li&gt;
&lt;li&gt;New genesis is written into db and initialized&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Main network services are started again pointing to the updated genesis&lt;&#x2F;li&gt;
&lt;li&gt;After the new genesis time is reached, the network starts again from the new genesis&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a full reset implementation, clients should be able to perform the above actions without requiring manual restart, operating the network fully independently and with minimal downtime.&lt;&#x2F;p&gt;
&lt;p&gt;Note that depending on the client architecture, it may not be feasible to fully implement such an internal reset mechanism, e.g. if the client doesn&#x27;t support a graceful shutdown. The reset feature is considered an advanced level of support and is mainly needed by infrastructure providers and genesis validators. The assumption is that even if the client doesn&#x27;t implement reset, advanced users can achieve similar behavior with external scripts handling the client by system tools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Ephemeral testnets with deterministic parameters provide a sustainable alternative to traditional testnets, with the same infrastructure. At each reset, the validator set is cleared, faucets are filled again and the database is kept small.&lt;&#x2F;p&gt;
&lt;p&gt;Upon reset the whole state is purged, which, on the one hand keeps the network small and easy to bootstrap but introduces problems for testing longer term &#x2F; advanced applications. However, basic contract infrastructure can be automatically deployed after each reset by any user. Generally, using the network is recommended for short term testing, deploying &lt;code&gt;Hello World&lt;&#x2F;code&gt; kinds of contracts that don&#x27;t need to stay forever on a long term testnet. However, there can be an offchain mechanism that automatically deploys standard contract primitives after each reset so application developers can also utilize the network more.&lt;&#x2F;p&gt;
&lt;p&gt;By defining two mechanisms for Genesis and Reset, this EIP enables two levels of how a client implementation can support the testnet;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Basic support requires the client to determine the current network specs and enables only connecting to the network.
&lt;ul&gt;
&lt;li&gt;This means support of the Genesis mechanism defined above&lt;&#x2F;li&gt;
&lt;li&gt;Enough to participate in the network for short term testing&lt;&#x2F;li&gt;
&lt;li&gt;To follow the latest iteration, the user has to manually shut down the client and delete the database&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s still recommended to add a feature for terminating the network&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Full support enables the client to follow the reset process and always sync the latest chain iteration
&lt;ul&gt;
&lt;li&gt;This also requires the client to implement an inherent Reset feature&lt;&#x2F;li&gt;
&lt;li&gt;Needed for running persistent infrastructure, genesis validators and bootnodes&lt;&#x2F;li&gt;
&lt;li&gt;It might be more complex to implement due to client architecture of clients&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The design is also compatible with nodes managed by external tooling, i.e. even if the client doesn&#x27;t implement these features, it can run on the same network as other nodes which are automatically reset by scripts. Any client supporting a custom network can be used for the testnet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;network-parameters&quot;&gt;Network parameters&lt;&#x2F;h3&gt;
&lt;p&gt;Constants and variables defining testnet properties are arbitrary but need to be crafted considering certain limitations and security properties set out below.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;reset-period&quot;&gt;Reset Period&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;period&lt;&#x2F;code&gt; is a constant, hardcoded in the client defining the period of time after which the network resets.&lt;&#x2F;p&gt;
&lt;p&gt;It can be defined based on users&#x27; needs but for security reasons, it also depends on the number of validators in genesis. Considering the time to activate a validator, the number of trusted validators should be high enough so the network cannot be overtaken by a malicious actor.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Genesis&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Validators&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; until&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 66%&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; majority&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;10k&lt;&#x2F;span&gt;&lt;span&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1289&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (5,7&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;50k&lt;&#x2F;span&gt;&lt;span&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6441&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (28,6&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;75k&lt;&#x2F;span&gt;&lt;span&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9660&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (42,9&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;100k&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12877&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (57,2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;150k&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19323&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (85,9&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;200k&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25764&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Epochs&lt;&#x2F;span&gt;&lt;span&gt; (114,5&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; days&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;chainid&quot;&gt;ChainId&lt;&#x2F;h4&gt;
&lt;p&gt;ChainId is a variable because it needs to keep changing with each new genesis to avoid replay attack. The function for the new ChainId value is a simple incrementation (+1). The ChainId in &lt;code&gt;genesis 0&lt;&#x2F;code&gt; is a hardcoded constant. This constant is used by the client with each new genesis to derive a new ChainId for that network iteration.&lt;&#x2F;p&gt;
&lt;p&gt;New ChainIds shouldn&#x27;t collide with any other existing public EVM chain even after many iterations. Consequently, low ChainId values are discouraged.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The network itself is providing a secure environment thanks to regular resets. Even if some sort of vulnerability is exploited, it will be cleared on the next reset. This is also a reason to keep periods relatively short (weeks&#x2F;months opposed to months&#x2F;years) with a big enough genesis validator set to keep an honest majority.&lt;&#x2F;p&gt;
&lt;p&gt;Changes in clients caused by the implementation of features for resetting networks need to be reviewed together with standard security procedures. Especially the mechanism for triggering reset which must be separated from other networks that are not configured as ephemeral.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Fungible Key Bound Token</title>
        <published>2023-03-31T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Mihai Onila</name><uri>https://github.com/MihaiORO</uri>
	</author>
	
	<author>
		<name>Nick Zeman</name><uri>https://github.com/NickZCZ</uri>
	</author>
	
	<author>
		<name>Narcis Cotaie</name><uri>https://github.com/NarcisCRO</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6808/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/fungible-key-bound-token-kbt/13624" />
        

        <id>https://wg-eips.ritovision.com/6808/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6808"
            label="ERC-6808" />
        

        
        

        
        <summary type="html">An interface for Fungible Key Bound Tokens, also known as a FKBT.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6808/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for Fungible Key Bound Tokens (&lt;strong&gt;FKBT&#x2F;s&lt;&#x2F;strong&gt;), a subset of the more general Key Bound Tokens (&lt;strong&gt;KBT&#x2F;s&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The following standardizes an API for tokens within smart contracts and provides basic functionality to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function. This function designates &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, which are responsible for conducting a &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. During this process, &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; are safely approved so they can be spent by the user or an on-chain third-party entity.&lt;&#x2F;p&gt;
&lt;p&gt;The premise of &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; is to provide fully optional security features built directly into the fungible asset, via the concept of &lt;em&gt;allow&lt;&#x2F;em&gt; found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; functions. These functions are called by one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-2&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;em&gt;allow&lt;&#x2F;em&gt; the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to either call the already familiar &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;approve&lt;&#x2F;code&gt; function found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;. Responsibility for the &lt;strong&gt;FKBT&lt;&#x2F;strong&gt; is therefore split. The &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; contains the asset and &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; have authority over how the assets can be spent or approved. &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; of a traditional fungible ERC-20 can be achieved by simply never using the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;We considered &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; being used by every individual who wishes to add additional security to their fungible assets, as well as consignment to third-party wallets&#x2F;brokers&#x2F;banks&#x2F;insurers. &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; are resilient to attacks&#x2F;thefts, by providing additional protection to the asset itself on a self-custodial level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;In this fast-paced technologically advancing world, people learn and mature at different speeds. The goal of global adoption must take into consideration the target demographic is of all ages and backgrounds. Unfortunately for self-custodial assets, one of the greatest pros is also one of its greatest cons. The individual is solely responsible for their actions and adequately securing their assets. If a mistake is made leading to a loss of funds, no one is able to guarantee their return.&lt;&#x2F;p&gt;
&lt;p&gt;From January 2021 through March 2022, the United States Federal Trade Commission received more than 46,000&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; crypto scam reports. This directly impacted crypto users and resulted in a net consumer loss exceeding $1 Billion&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-6-1&quot;&gt;&lt;a href=&quot;#fn-6&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Theft and malicious scams are an issue in any financial sector and oftentimes lead to stricter regulation. However, government-imposed regulation goes against one of this space’s core values. Efforts have been made to increase security within the space through centralized and decentralized means. Up until now, no one has offered a solution that holds onto the advantages of both whilst eliminating their disadvantages.&lt;&#x2F;p&gt;
&lt;p&gt;We asked ourselves the same question as many have in the past, “How does one protect the wallet?”. After a while, realizing the question that should be asked is “How does one protect the asset?”. Creating the wallet is free, the asset is what has value and is worth protecting. This question led to the development of &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt;. A solution that is fully optional and can be tailored so far as the user is concerned. Individual assets remain protected even if the seed phrase or private key is publicly released, as long as the security feature was activated.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; saw the need to improve on the widely used fungible ERC-20 token standard. The security of fungible assets is a topic that concerns every entity in the crypto space, as their current and future use cases are continuously explored. &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; provide a scalable decentralized security solution that takes security one step beyond wallet security, focusing on the token&#x27;s ability to remain secure. The security is on the blockchain itself, which allows every demographic that has access to the internet to secure their assets without the need for current hardware or centralized solutions. Made to be a promising alternative, &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; inherit all the characteristics of an ERC-20. This was done so &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; could be used on every dApp that is configured to use traditional fungible tokens.&lt;&#x2F;p&gt;
&lt;p&gt;During the development process, the potential advantages &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; explored were the main motivation factors leading to their creation;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Completely Decentralized:&lt;&#x2F;strong&gt; The security features are fully decentralized meaning no third-party will have access to user funds when activated. This was done to truly stay in line with the premise of self-custodial assets, responsibility and values.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Limitless Scalability:&lt;&#x2F;strong&gt; Centralized solutions require the creation of an account and their availability may be restricted based on location. &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; do not face regional restrictions or account creation. Decentralized security solutions such as hardware options face scalability issues requiring transport logistics, secure shipping and vendor. &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; can be used anywhere around the world by anyone who so wishes, provided they have access to the internet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fully Optional Security:&lt;&#x2F;strong&gt; Security features are optional, customizable and removable. It’s completely up to the user to decide the level of security they would like when using &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Default Functionality:&lt;&#x2F;strong&gt; If the user would like to use &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; as a traditional ERC-20, the security features do not have to be activated. As the token inherits all of the same characteristics, it results in the token acting with traditional fungible &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-2&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. However, even when the security features are activated, the user will still have the ability to customize the functionality of the various features based on their desired outcome. The user can pass a set of custom and or &lt;strong&gt;Default Values&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-1&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; manually or through a dApp.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unmatched Security:&lt;&#x2F;strong&gt; By calling the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function a &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-3&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is now required for the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function. The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function requires 4 parameters, &lt;code&gt;_amount&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-1&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-1&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, &lt;code&gt;_address&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-1&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, and &lt;code&gt;_allFunds&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-11-1&quot;&gt;&lt;a href=&quot;#fn-11&quot;&gt;11&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, where as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function has 2 parameters, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-1&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-1&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. In addition to this, &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; have a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function. The combination of all these prevent and virtually cover every single point of failure that is present with a traditional ERC-20, when properly used.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security Fail-Safes:&lt;&#x2F;strong&gt; With &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt;, users can be confident that their tokens are safe and secure, even if the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-2&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-4&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. If the owner suspects that the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; has been compromised or lost access, they can call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; function from one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;. This moves the assets to the other &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt; preventing a single point of failure. If the owner suspects that one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; has been comprised or lost access, the owner can call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function from &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-1&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-1&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. This resets the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; security feature and allows the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; to call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function again. New &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; can therefore be added and a single point of failure can be prevented.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Anonymous Security:&lt;&#x2F;strong&gt; Frequently, centralized solutions ask for personal information that is stored and subject to prying eyes. Purchasing decentralized hardware solutions are susceptible to the same issues e.g. a shipping address, payment information, or a camera recording during a physical cash pick-up. This may be considered by some as infringing on their privacy and asset anonymity. &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; ensure user confidentially as everything can be done remotely under a pseudonym on the blockchain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Low-Cost Security:&lt;&#x2F;strong&gt; The cost of using &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; security features correlate to on-chain fees, the current &lt;em&gt;GWEI&lt;&#x2F;em&gt; at the given time. As a standalone solution, they are a viable cost-effective security measure feasible to the majority of the population.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Environmentally Friendly:&lt;&#x2F;strong&gt; Since the security features are coded into the &lt;strong&gt;FKBT&lt;&#x2F;strong&gt;, there is no need for centralized servers, shipping, or the production of physical object&#x2F;s. Thus leading to a minimal carbon footprint by the use of &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;, working hand in hand with Ethereum’s change to a &lt;em&gt;PoS&lt;&#x2F;em&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-14-1&quot;&gt;&lt;a href=&quot;#fn-14&quot;&gt;16&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; network.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User Experience:&lt;&#x2F;strong&gt; The security feature can be activated by a simple call to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function. The user will only need two other wallets, which will act as &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-2&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-2&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, to gain access to all of the benefits &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; offer. The optional security features improve the overall user experience and Ethereum ecosystem by ensuring a safety net for those who decide to use it. Those that do not use the security features are not hindered in any way. This safety net can increase global adoption as people can remain confident in the security of their assets, even in the scenario of a compromised wallet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ikbt20-token-contract&quot;&gt;&lt;code&gt;IKBT20&lt;&#x2F;code&gt; (Token Contract)&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;NOTES&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The following specifications use syntax from Solidity &lt;code&gt;0.8.0&lt;&#x2F;code&gt; (or above)&lt;&#x2F;li&gt;
&lt;li&gt;Callers MUST handle &lt;code&gt;false&lt;&#x2F;code&gt; from &lt;code&gt;returns (bool success)&lt;&#x2F;code&gt;. Callers MUST NOT assume that &lt;code&gt;false&lt;&#x2F;code&gt; is never returned!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IKBT20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountSecured&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountResetBinding&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SafeFallbackActivated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _allFunds&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _numberOfTransfers&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Ingress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Egress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountHolderBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FirstAccountBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; accountHolderWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SecondAccountBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; accountHolderWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; allFunds&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; numberOfTransfers&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet2&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AccountHolderBindings&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resetBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _allFunds&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTransferableFunds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _numberOfTransfers&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ApprovalConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getNumberOfTransfersAllowed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isSecureWallet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;accountsecured-event&quot;&gt;&lt;code&gt;AccountSecured&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the &lt;code&gt;_account&lt;&#x2F;code&gt; is securing his account by calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;_amount&lt;&#x2F;code&gt; is the current balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountSecured&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountresetbinding-event&quot;&gt;&lt;code&gt;AccountResetBinding&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the holder is resetting his &lt;code&gt;keyWallets&lt;&#x2F;code&gt; by calling the &lt;code&gt;resetBindings&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountResetBinding&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;safefallbackactivated-event&quot;&gt;&lt;code&gt;SafeFallbackActivated&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the holder is choosing to move all the funds to one of the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; by calling the &lt;code&gt;safeFallback&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SafeFallbackActivated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountenabledtransfer-event&quot;&gt;&lt;code&gt;AccountEnabledTransfer&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed for transfer an &lt;code&gt;_amount&lt;&#x2F;code&gt; of tokens for the &lt;code&gt;_time&lt;&#x2F;code&gt; amount of &lt;code&gt;block&lt;&#x2F;code&gt; seconds for &lt;code&gt;_to&lt;&#x2F;code&gt; address (or if
the &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed for transfer all funds though &lt;code&gt;_allFunds&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt;) by calling the &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _allFunds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountenabledapproval-event&quot;&gt;&lt;code&gt;AccountEnabledApproval&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed approval, for the &lt;code&gt;_time&lt;&#x2F;code&gt; amount of &lt;code&gt;block&lt;&#x2F;code&gt; seconds and set a &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt; allowed, by calling the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _numberOfTransfers&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;ingress-event&quot;&gt;&lt;code&gt;Ingress&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; becomes a holder. &lt;code&gt;_amount&lt;&#x2F;code&gt; is the current balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Ingress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;egress-event&quot;&gt;&lt;code&gt;Egress&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; transfers all his tokens and is no longer a holder. &lt;code&gt;_amount&lt;&#x2F;code&gt; is the previous balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Egress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&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;interface-functions&quot;&gt;&lt;strong&gt;Interface functions&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The functions detailed below MUST be implemented.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;addbindings-function&quot;&gt;&lt;code&gt;addBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Secures the sender account with other two wallets called &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; and MUST fire the &lt;code&gt;AccountSecured&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is not a holder&lt;&#x2F;li&gt;
&lt;li&gt;or the sender is already secured&lt;&#x2F;li&gt;
&lt;li&gt;or the keyWallets are the same&lt;&#x2F;li&gt;
&lt;li&gt;or one of the keyWallets is the same as the sender&lt;&#x2F;li&gt;
&lt;li&gt;or one or both keyWallets are zero address (&lt;code&gt;0x0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;or one or both keyWallets are already keyWallets to another holder account&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addBindings&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;getbindings-function&quot;&gt;&lt;code&gt;getBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; for the &lt;code&gt;_account&lt;&#x2F;code&gt; in a &lt;code&gt;struct&lt;&#x2F;code&gt; format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountHolderBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AccountHolderBindings&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;h4 id=&quot;resetbindings-function&quot;&gt;&lt;code&gt;resetBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; This function is helpful when one of the two &lt;code&gt;keyWallets&lt;&#x2F;code&gt; is compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, the function resets the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; for the &lt;code&gt;holder&lt;&#x2F;code&gt; account. MUST fire the &lt;code&gt;AccountResetBinding&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resetBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;safefallback-function&quot;&gt;&lt;code&gt;safeFallback&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; This function is helpful when the &lt;code&gt;holder&lt;&#x2F;code&gt; account is compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function transfers all the tokens from the &lt;code&gt;holder&lt;&#x2F;code&gt; account to the other &lt;code&gt;keyWallet&lt;&#x2F;code&gt; and MUST fire the &lt;code&gt;SafeFallbackActivated&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowtransfer-function&quot;&gt;&lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function is called before a &lt;code&gt;transfer&lt;&#x2F;code&gt; function is called.&lt;&#x2F;p&gt;
&lt;p&gt;It allows to transfer a maximum amount, for a specific time frame, to a specific address.&lt;&#x2F;p&gt;
&lt;p&gt;If the amount is 0 then there will be no restriction on the amount.
If the time is 0 then there will be no restriction on the time.
If the to address is zero address then there will be no restriction on the to address.
Or if &lt;code&gt;_allFunds&lt;&#x2F;code&gt; is &lt;code&gt;true&lt;&#x2F;code&gt;, regardless of the other params, it allows all funds, whenever, to anyone to be transferred.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire &lt;code&gt;AccountEnabledTransfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt; or if the &lt;code&gt;_amount&lt;&#x2F;code&gt; is greater than the &lt;code&gt;holder&lt;&#x2F;code&gt; account balance.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _allFunds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;gettransferablefunds-function&quot;&gt;&lt;code&gt;getTransferableFunds&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the transfer conditions for the &lt;code&gt;_account&lt;&#x2F;code&gt; in a &lt;code&gt;struct&lt;&#x2F;code&gt; format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; allFunds&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTransferableFunds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowapproval-function&quot;&gt;&lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function is called before one of the &lt;code&gt;approve&lt;&#x2F;code&gt;, &lt;code&gt;increaseAllowance&lt;&#x2F;code&gt; or &lt;code&gt;decreaseAllowance&lt;&#x2F;code&gt; function are called.&lt;&#x2F;p&gt;
&lt;p&gt;It allows the &lt;code&gt;holder&lt;&#x2F;code&gt; for a specific amount of &lt;code&gt;_time&lt;&#x2F;code&gt; to do an &lt;code&gt;approve&lt;&#x2F;code&gt;, &lt;code&gt;increaseAllowance&lt;&#x2F;code&gt; or &lt;code&gt;decreaseAllowance&lt;&#x2F;code&gt; and limit the number of transfers the spender is allowed to do through &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt; (0 - unlimited number of transfers in the allowance limit).&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire &lt;code&gt;AccountEnabledApproval&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _numberOfTransfers&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;getapprovalconditions-function&quot;&gt;&lt;code&gt;getApprovalConditions&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the approval conditions in a struct format. Where &lt;code&gt;time&lt;&#x2F;code&gt; is the &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; until the &lt;code&gt;approve&lt;&#x2F;code&gt;, &lt;code&gt;increaseAllowance&lt;&#x2F;code&gt; or &lt;code&gt;decreaseAllowance&lt;&#x2F;code&gt; functions can be called, and &lt;code&gt;numberOfTransfers&lt;&#x2F;code&gt; is the number of transfers the spender will be allowed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; numberOfTransfers&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ApprovalConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transfer-function&quot;&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function transfers &lt;code&gt;_amount&lt;&#x2F;code&gt; of tokens to address &lt;code&gt;_to&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender’s account balance does not have enough tokens to spend, or if the sender is a secure account and it has not allowed the transfer of funds through &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; Transfers of &lt;code&gt;0&lt;&#x2F;code&gt; values MUST be treated as normal transfers and fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;approve-function&quot;&gt;&lt;code&gt;approve&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function allows &lt;code&gt;_spender&lt;&#x2F;code&gt; to transfer from the &lt;code&gt;holder&lt;&#x2F;code&gt; account multiple times, up to the &lt;code&gt;_value&lt;&#x2F;code&gt; amount.&lt;&#x2F;p&gt;
&lt;p&gt;The function also limits the &lt;code&gt;_spender&lt;&#x2F;code&gt; to the specific number of transfers set in the &lt;code&gt;ApprovalConditions&lt;&#x2F;code&gt; for that &lt;code&gt;holder&lt;&#x2F;code&gt; account. If the value is &lt;code&gt;0&lt;&#x2F;code&gt; then the &lt;code&gt;_spender&lt;&#x2F;code&gt; can transfer multiple times, up to the &lt;code&gt;_value&lt;&#x2F;code&gt; amount.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire an &lt;code&gt;Approval&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;If this function is called again it overrides the current allowance with &lt;code&gt;_value&lt;&#x2F;code&gt; and also overrides the number of transfers allowed with &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;, set in &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is secured and has not called &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_time&lt;&#x2F;code&gt;, set in the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function, has elapsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;increaseallowance-function&quot;&gt;&lt;code&gt;increaseAllowance&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function increases the allowance granted to &lt;code&gt;_spender&lt;&#x2F;code&gt; to withdraw from your account.&lt;&#x2F;p&gt;
&lt;p&gt;The function Emits an &lt;code&gt;Approval&lt;&#x2F;code&gt; event indicating the updated allowance.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is secured and has not called &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_spender&lt;&#x2F;code&gt; is a zero address (&lt;code&gt;0x0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_time&lt;&#x2F;code&gt;, set in the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function, has elapsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; increaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addedValue&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;decreaseallowance-function&quot;&gt;&lt;code&gt;decreaseAllowance&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function decreases the allowance granted to &lt;code&gt;_spender&lt;&#x2F;code&gt; to withdraw from your account.&lt;&#x2F;p&gt;
&lt;p&gt;The function Emits an &lt;code&gt;Approval&lt;&#x2F;code&gt; event indicating the updated allowance.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is secured and has not called &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_spender&lt;&#x2F;code&gt; is a zero address (&lt;code&gt;0x0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_time&lt;&#x2F;code&gt;, set in the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function, has elapsed.&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_subtractedValue&lt;&#x2F;code&gt; is greater than the current allowance&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decreaseAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _subtractedValue&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;transferfrom-function&quot;&gt;&lt;code&gt;transferFrom&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function transfers &lt;code&gt;_amount&lt;&#x2F;code&gt; of tokens from address &lt;code&gt;_from&lt;&#x2F;code&gt; to address &lt;code&gt;_to&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;transferFrom&lt;&#x2F;code&gt; method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf.
The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; unless the &lt;code&gt;_from&lt;&#x2F;code&gt; account has deliberately authorized the sender.
Each time the spender calls the function the contract subtracts and checks if the number of allowed transfers has reached 0,
and when that happens the approval is revoked using an approve of 0 amount.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; Transfers of 0 values MUST be treated as normal transfers and fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The intent from individual technical decisions made during the development of &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; focused on maintaining consistency and backward compatibility with ERC-20s, all the while offering self-custodial security features to the user. It was important that &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; inherited all of ERC-20s characteristics to comply with requirements found in dApps which use fungible tokens on their platform. In doing so, it allowed for flawless backward compatibility to take place and gave the user the choice to decide if they want their &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; to act with &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-3&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. We wanted to ensure that wide-scale implementation and adoption of &lt;strong&gt;FKBTs&lt;&#x2F;strong&gt; could take place immediately, without the greater collective needing to adapt and make changes to the already flourishing decentralized ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;For developers and users alike, the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; functions both return bools on success and revert on failures. This decision was done purposefully, to keep consistency with the already familiar ERC-20. Additional technical decisions related to self-custodial security features are broken down and located within the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#security-considerations&quot;&gt;Security Considerations&lt;&#x2F;a&gt; section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; are designed to be backward-compatible with existing token standards and wallets. Existing tokens and wallets will continue to function as normal, and will not be affected by the implementation of &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;assets&#x2F;README&#x2F;&quot;&gt;assets&lt;&#x2F;a&gt; directory has all the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;.&#x2F;assets&#x2F;test&#x2F;kbt20.js&quot;&gt;tests&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Average Gas used (&lt;em&gt;GWEI&lt;&#x2F;em&gt;):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;addBindings&lt;&#x2F;code&gt; - 154,991&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resetBindings&lt;&#x2F;code&gt; - 30,534&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;safeFallback&lt;&#x2F;code&gt; - 51,013&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;allowTransfer&lt;&#x2F;code&gt; - 49,887&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;allowApproval&lt;&#x2F;code&gt; - 44,971&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation is located in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;assets&#x2F;README&#x2F;&quot;&gt;assets&lt;&#x2F;a&gt; directory. There&#x27;s also a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;.&#x2F;assets&#x2F;Contract%20Interactions%20diagram.svg&quot;&gt;diagram&lt;&#x2F;a&gt; with the contract interactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; were designed with security in mind every step of the way. Below are some design decisions that were rigorously discussed and thought through during the development process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-5&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: When calling the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function for an &lt;strong&gt;FKBT&lt;&#x2F;strong&gt;, the user must input 2 wallets that will then act as &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-3&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-3&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. They are added simultaneously to reduce user fees, minimize the chance of human error and prevent a pitfall scenario. If the user had the ability to add multiple wallets it would not only result in additional fees and avoidable confusion but would enable a potentially disastrous &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; situation to occur. For this reason, all &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; work under a 3-wallet system when security features are activated.&lt;&#x2F;p&gt;
&lt;p&gt;Typically if a wallet is compromised, the fungible assets within are at risk. With &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; there are two different functions that can be called from a &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-6&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; depending on which wallet has been compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Scenario: &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-3&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised, call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt;: This function was created in the event that the owner believes the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-4&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. It can also be used if the owner losses access to the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;. In this scenario, the user has the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; from one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-7&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; are then redirected from the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; to the other &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By redirecting the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; it prevents a single point of failure. If an attacker were to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; and the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; redirected to the &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-8&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; that called the function, they would gain access to all the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Scenario: &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-9&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised, call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;: This function was created in the event that the owner believes &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-4&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-4&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. It can also be used if the owner losses access to one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-10&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. In this instance, the user has the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;, removing the bound &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; and resetting the security features. The &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; will now function as a traditional ERC-20 until &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; is called again and a new set of &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; are added.&lt;&#x2F;p&gt;
&lt;p&gt;The reason why &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-5&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-5&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; are required to call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function is because a &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-5&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; having the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; could result in an immediate loss of &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;. The attacker would only need to gain access to the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; and call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the scenario that 2 of the 3 wallets have been compromised, there is nothing the owner of the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; can do if the attack is malicious. However, by allowing 1 wallet to be compromised, holders of fungible tokens built using the &lt;strong&gt;FKBT&lt;&#x2F;strong&gt; standard are given a second chance, unlike other current standards.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function is in place to guarantee a &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-2&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, but can also have &lt;strong&gt;Default Values&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-2&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; set by a dApp to emulate &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-6&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; of a traditional ERC-20. It enables the user to highly specify the type of transfer they are about to conduct, whilst simultaneously allowing the user to unlock all the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; to anyone for an unlimited amount of time. The desired security is completely up to the user.&lt;&#x2F;p&gt;
&lt;p&gt;This function requires 4 parameters to be filled and different combinations of these result in different levels of security;&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 1 &lt;code&gt;_amount&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-2&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: This is the number of &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; that will be spent on a transfer.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 2 &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-2&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of blocks the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; can be transferred starting from the current block timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 3 &lt;code&gt;_address&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-2&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The destination the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; will be sent to.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 4 &lt;code&gt;_allFunds&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-11-2&quot;&gt;&lt;a href=&quot;#fn-11&quot;&gt;11&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: This is a boolean value. When false, the &lt;code&gt;transfer&lt;&#x2F;code&gt; function takes into consideration Parameters 1, 2 and 3. If the value is true, the &lt;code&gt;transfer&lt;&#x2F;code&gt; function will revert to a &lt;strong&gt;Default Behavior&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-4&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the same as a traditional ERC-20.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function requires &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-6&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-6&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and enables the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-7&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to conduct a &lt;code&gt;transfer&lt;&#x2F;code&gt; within the previously specified parameters. These parameters were added in order to provide additional security by limiting the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; in case it was compromised without the user&#x27;s knowledge.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function provides extra security when allowing on-chain third parties to use your &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; on your behalf. This is especially useful when a user is met with common malicious attacks e.g. draining dApp.&lt;&#x2F;p&gt;
&lt;p&gt;This function requires 2 parameters to be filled and different combinations of these result in different levels of security;&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 1 &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-2&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of blocks that the approval of a third-party service can take place, starting from the current block timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 2 &lt;code&gt;_numberOfTransfers_&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-2&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of transactions a third-party service can conduct on the user&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6808&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function requires &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-7&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-7&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and enables the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-8&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to allow a third-party service by using the &lt;code&gt;approve&lt;&#x2F;code&gt; function. These parameters were added to provide extra security when granting permission to a third-party that uses assets on the user&#x27;s behalf. Parameter 1, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-3&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, is a limitation to when the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; can &lt;code&gt;approve&lt;&#x2F;code&gt; a third-party service. Parameter 2, &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-3&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, is a limitation to the number of transactions the approved third-party service can conduct on the user&#x27;s behalf before revoking approval.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;The &lt;strong&gt;Key Wallet&#x2F;s&lt;&#x2F;strong&gt; refers to &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; which can call the &lt;code&gt;safeFallback&lt;&#x2F;code&gt;, &lt;code&gt;resetBindings&lt;&#x2F;code&gt;, &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; and &lt;code&gt;allowApproval&lt;&#x2F;code&gt; functions. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-7&quot;&gt;↩7&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-8&quot;&gt;↩8&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-9&quot;&gt;↩9&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-10&quot;&gt;↩10&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt; is when 1 of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; safely approved the use of the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-2-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;The &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; refers to the wallet containing the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-7&quot;&gt;↩7&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-8&quot;&gt;↩8&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Default Behavior&#x2F;s&lt;&#x2F;strong&gt; refers to behavior&#x2F;s present in the preexisting non-fungible ERC-20 standard. &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-4&quot;&gt;↩4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;The number of crypto scam reports the United States Federal Trade Commission received, from January 2021 through March 2022. &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;The amount stolen via crypto scams according to the United States Federal Trade Commission, from January 2021 through March 2022. &lt;a href=&quot;#fr-6-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Default Value&#x2F;s&lt;&#x2F;strong&gt; refer to a value&#x2F;s that emulates the non-fungible ERC-20 &lt;strong&gt;Default Behavior&#x2F;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-7-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-7-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;The &lt;code&gt;_amount&lt;&#x2F;code&gt; represents the amount of the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; intended to be spent. &lt;a href=&quot;#fr-8-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-8-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-9&quot;&gt;
&lt;p&gt;The &lt;code&gt;_time&lt;&#x2F;code&gt; in &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; represents the number of blocks a &lt;code&gt;transfer&lt;&#x2F;code&gt; can take place in. &lt;a href=&quot;#fr-9-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-9-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-10&quot;&gt;
&lt;p&gt;The &lt;code&gt;_address&lt;&#x2F;code&gt; represents the address that the &lt;strong&gt;FKBT&#x27;s&lt;&#x2F;strong&gt; will be sent to. &lt;a href=&quot;#fr-10-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-10-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-11&quot;&gt;
&lt;p&gt;The &lt;code&gt;_allFunds&lt;&#x2F;code&gt; is a bool that can be set to true or false. &lt;a href=&quot;#fr-11-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-11-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-12&quot;&gt;
&lt;p&gt;The &lt;code&gt;_time&lt;&#x2F;code&gt; in &lt;code&gt;allowApproval&lt;&#x2F;code&gt; represents the number of blocks an &lt;code&gt;approve&lt;&#x2F;code&gt; can take place in. &lt;a href=&quot;#fr-12-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-12-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-12-3&quot;&gt;↩3&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-13&quot;&gt;
&lt;p&gt;The &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt; is the number of transfers a third-party entity can conduct via &lt;code&gt;transfer&lt;&#x2F;code&gt; on the user&#x27;s behalf. &lt;a href=&quot;#fr-13-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-13-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-13-3&quot;&gt;↩3&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-15&quot;&gt;
&lt;p&gt;The &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; is 1 of the 2 &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; set when calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function. &lt;a href=&quot;#fr-15-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-7&quot;&gt;↩7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-16&quot;&gt;
&lt;p&gt;The &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; is 1 of the 2 &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; set when calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function. &lt;a href=&quot;#fr-16-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-7&quot;&gt;↩7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-14&quot;&gt;
&lt;p&gt;A &lt;em&gt;PoS&lt;&#x2F;em&gt; protocol, Proof-of-Stake protocol, is a cryptocurrency consensus mechanism for processing transactions and creating new blocks in a blockchain. &lt;a href=&quot;#fr-14-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Non-Fungible Key Bound Token</title>
        <published>2023-03-31T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Mihai Onila</name><uri>https://github.com/MihaiORO</uri>
	</author>
	
	<author>
		<name>Nick Zeman</name><uri>https://github.com/NickZCZ</uri>
	</author>
	
	<author>
		<name>Narcis Cotaie</name><uri>https://github.com/NarcisCRO</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6809/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/non-fungible-key-bound-token-kbt/13625" />
        

        <id>https://wg-eips.ritovision.com/6809/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6809"
            label="ERC-6809" />
        

        
        

        
        <summary type="html">An interface for Non-Fungible Key Bound Tokens, also known as a NFKBT.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6809/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for Non-Fungible Key Bound Tokens (&lt;strong&gt;NFKBT&#x2F;s&lt;&#x2F;strong&gt;), a subset of the more general Key Bound Tokens (&lt;strong&gt;KBT&#x2F;s&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The following standardizes an API for tokens within smart contracts and provides basic functionality to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function. This function designates &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, which are responsible for conducting a &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. During this process, &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; are safely approved so they can be spent by the user or an on-chain third-party entity.&lt;&#x2F;p&gt;
&lt;p&gt;The premise of &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; is to provide fully optional security features built directly into the non-fungible asset, via the concept of &lt;em&gt;allow&lt;&#x2F;em&gt; found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; functions. These functions are called by one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-2&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;em&gt;allow&lt;&#x2F;em&gt; the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to either call the already familiar &lt;code&gt;transferFrom&lt;&#x2F;code&gt; and &lt;code&gt;approve&lt;&#x2F;code&gt; function found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. Responsibility for the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; is therefore split. The &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; contains the asset and &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; have authority over how the assets can be spent or approved. &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; of a traditional non-fungible ERC-721 can be achieved by simply never using the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;We considered &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; being used by every individual who wishes to add additional security to their non-fungible assets, as well as consignment to third-party wallets&#x2F;brokers&#x2F;banks&#x2F;insurers&#x2F;galleries. &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; are resilient to attacks&#x2F;thefts, by providing additional protection to the asset itself on a self-custodial level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;In this fast-paced technologically advancing world, people learn and mature at different speeds. The goal of global adoption must take into consideration the target demographic is of all ages and backgrounds. Unfortunately for self-custodial assets, one of the greatest pros is also one of its greatest cons. The individual is solely responsible for their actions and adequately securing their assets. If a mistake is made leading to a loss of funds, no one is able to guarantee their return.&lt;&#x2F;p&gt;
&lt;p&gt;From January 2021 through March 2022, the United States Federal Trade Commission received more than 46,000&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; crypto scam reports. This directly impacted crypto users and resulted in a net consumer loss exceeding $1 Billion&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-6-1&quot;&gt;&lt;a href=&quot;#fn-6&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Theft and malicious scams are an issue in any financial sector and oftentimes lead to stricter regulation. However, government-imposed regulation goes against one of this space’s core values. Efforts have been made to increase security within the space through centralized and decentralized means. Up until now, no one has offered a solution that holds onto the advantages of both whilst eliminating their disadvantages.&lt;&#x2F;p&gt;
&lt;p&gt;We asked ourselves the same question as many have in the past, “How does one protect the wallet?”. After a while, realizing the question that should be asked is “How does one protect the asset?”. Creating the wallet is free, the asset is what has value and is worth protecting. This question led to the development of &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt;. A solution that is fully optional and can be tailored so far as the user is concerned. Individual assets remain protected even if the seed phrase or private key is publicly released, as long as the security feature was activated.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; saw the need to improve on the widely used non-fungible ERC-721 token standard. The security of non-fungible assets is a topic that concerns every entity in the crypto space, as their current and future use cases are continuously explored. &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; provide a scalable decentralized security solution that takes security one step beyond wallet security, focusing on the token&#x27;s ability to remain secure. The security is on the blockchain itself, which allows every demographic that has access to the internet to secure their assets without the need for current hardware or centralized solutions. Made to be a promising alternative, &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; inherit all the characteristics of an ERC-721. This was done so &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; could be used on every dApp that is configured to use traditional non-fungible tokens.&lt;&#x2F;p&gt;
&lt;p&gt;During the development process, the potential advantages &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; explored were the main motivation factors leading to their creation;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Completely Decentralized:&lt;&#x2F;strong&gt; The security features are fully decentralized meaning no third-party will have access to user funds when activated. This was done to truly stay in line with the premise of self-custodial assets, responsibility and values.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Limitless Scalability:&lt;&#x2F;strong&gt; Centralized solutions require the creation of an account and their availability may be restricted based on location. &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; do not face regional restrictions or account creation. Decentralized security solutions such as hardware options face scalability issues requiring transport logistics, secure shipping and vendor. &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; can be used anywhere around the world by anyone who so wishes, provided they have access to the internet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fully Optional Security:&lt;&#x2F;strong&gt; Security features are optional, customizable and removable. It’s completely up to the user to decide the level of security they would like when using &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Default Functionality:&lt;&#x2F;strong&gt; If the user would like to use &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; as a traditional ERC-721, the security features do not have to be activated. As the token inherits all of the same characteristics, it results in the token acting with traditional non-fungible &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-2&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. However, even when the security features are activated, the user will still have the ability to customize the functionality of the various features based on their desired outcome. The user can pass a set of custom and or &lt;strong&gt;Default Values&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-1&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; manually or through a dApp.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unmatched Security:&lt;&#x2F;strong&gt; By calling the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function a &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-3&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is now required for the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function. The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function requires 4 parameters, &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-1&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-1&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, &lt;code&gt;_address&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-1&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, and &lt;code&gt;_anyToken&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-11-1&quot;&gt;&lt;a href=&quot;#fn-11&quot;&gt;11&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, where as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function has 2 parameters, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-1&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-1&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. In addition to this, &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; have a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function. The combination of all these prevent and virtually cover every single point of failure that is present with a traditional ERC-721, when properly used.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security Fail-Safes:&lt;&#x2F;strong&gt; With &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt;, users can be confident that their tokens are safe and secure, even if the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-2&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-4&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. If the owner suspects that the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; has been compromised or lost access, they can call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; function from one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;. This moves the assets to the other &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt; preventing a single point of failure. If the owner suspects that one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; has been comprised or lost access, the owner can call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function from &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-1&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-1&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. This resets the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; security feature and allows the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; to call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function again. New &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; can therefore be added and a single point of failure can be prevented.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Anonymous Security:&lt;&#x2F;strong&gt; Frequently, centralized solutions ask for personal information that is stored and subject to prying eyes. Purchasing decentralized hardware solutions are susceptible to the same issues e.g. a shipping address, payment information, or a camera recording during a physical cash pick-up. This may be considered by some as infringing on their privacy and asset anonymity. &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; ensure user confidentially as everything can be done remotely under a pseudonym on the blockchain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Low-Cost Security:&lt;&#x2F;strong&gt; The cost of using &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; security features correlate to on-chain fees, the current &lt;em&gt;GWEI&lt;&#x2F;em&gt; at the given time. As a standalone solution, they are a viable cost-effective security measure feasible to the majority of the population.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Environmentally Friendly:&lt;&#x2F;strong&gt; Since the security features are coded into the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt;, there is no need for centralized servers, shipping, or the production of physical object&#x2F;s. Thus leading to a minimal carbon footprint by the use of &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;, working hand in hand with Ethereum’s change to a &lt;em&gt;PoS&lt;&#x2F;em&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-14-1&quot;&gt;&lt;a href=&quot;#fn-14&quot;&gt;16&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; network.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User Experience:&lt;&#x2F;strong&gt; The security feature can be activated by a simple call to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function. The user will only need two other wallets, which will act as &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-2&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-2&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, to gain access to all of the benefits &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; offer. The optional security features improve the overall user experience and Ethereum ecosystem by ensuring a safety net for those who decide to use it. Those that do not use the security features are not hindered in any way. This safety net can increase global adoption as people can remain confident in the security of their assets, even in the scenario of a compromised wallet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ikbt721-token-contract&quot;&gt;&lt;code&gt;IKBT721&lt;&#x2F;code&gt; (Token Contract)&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;NOTES&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The following specifications use syntax from Solidity &lt;code&gt;0.8.17&lt;&#x2F;code&gt; (or above)&lt;&#x2F;li&gt;
&lt;li&gt;Callers MUST handle &lt;code&gt;false&lt;&#x2F;code&gt; from &lt;code&gt;returns (bool success)&lt;&#x2F;code&gt;. Callers MUST NOT assume that &lt;code&gt;false&lt;&#x2F;code&gt; is never returned!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IKBT721&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountSecured&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _noOfTokens&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountResetBinding&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SafeFallbackActivated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _anyToken&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _numberOfTransfers&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Ingress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Egress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountHolderBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FirstAccountBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; accountHolderWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SecondAccountBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; accountHolderWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; anyToken&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; numberOfTransfers&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet2&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AccountHolderBindings&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resetBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _allTokens&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTransferableFunds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _numberOfTransfers&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ApprovalConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getNumberOfTransfersAllowed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isSecureWallet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isSecureToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;accountsecured-event&quot;&gt;&lt;code&gt;AccountSecured&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the &lt;code&gt;_account&lt;&#x2F;code&gt; is securing his account by calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;_amount&lt;&#x2F;code&gt; is the current balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountSecured&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountresetbinding-event&quot;&gt;&lt;code&gt;AccountResetBinding&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the holder is resetting his &lt;code&gt;keyWallets&lt;&#x2F;code&gt; by calling the &lt;code&gt;resetBindings&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountResetBinding&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;safefallbackactivated-event&quot;&gt;&lt;code&gt;SafeFallbackActivated&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the holder is choosing to move all the funds to one of the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; by calling the &lt;code&gt;safeFallback&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SafeFallbackActivated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountenabledtransfer-event&quot;&gt;&lt;code&gt;AccountEnabledTransfer&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when the &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed for transfer &lt;code&gt;_amount&lt;&#x2F;code&gt; of tokens for the &lt;code&gt;_time&lt;&#x2F;code&gt; amount of &lt;code&gt;block&lt;&#x2F;code&gt; seconds for &lt;code&gt;_to&lt;&#x2F;code&gt; address (or if
the &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed for transfer all funds though &lt;code&gt;_anyToken&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt;) by calling the &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _allFunds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;accountenabledapproval-event&quot;&gt;&lt;code&gt;AccountEnabledApproval&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; has allowed approval for the &lt;code&gt;_time&lt;&#x2F;code&gt; amount of &lt;code&gt;block&lt;&#x2F;code&gt; seconds by calling the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountEnabledApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;ingress-event&quot;&gt;&lt;code&gt;Ingress&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; becomes a holder. &lt;code&gt;_amount&lt;&#x2F;code&gt; is the current balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Ingress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;egress-event&quot;&gt;&lt;code&gt;Egress&lt;&#x2F;code&gt; event&lt;&#x2F;h4&gt;
&lt;p&gt;Emitted when &lt;code&gt;_account&lt;&#x2F;code&gt; transfers all his tokens and is no longer a holder. &lt;code&gt;_amount&lt;&#x2F;code&gt; is the previous balance of the &lt;code&gt;_account&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Egress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&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;interface-functions&quot;&gt;&lt;strong&gt;Interface functions&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The functions detailed below MUST be implemented.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;addbindings-function&quot;&gt;&lt;code&gt;addBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Secures the sender account with other two wallets called &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; and MUST fire the &lt;code&gt;AccountSecured&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is not a holder&lt;&#x2F;li&gt;
&lt;li&gt;or the sender is already secured&lt;&#x2F;li&gt;
&lt;li&gt;or the keyWallets are the same&lt;&#x2F;li&gt;
&lt;li&gt;or one of the keyWallets is the same as the sender&lt;&#x2F;li&gt;
&lt;li&gt;or one or both keyWallets are zero address (&lt;code&gt;0x0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;or one or both keyWallets are already keyWallets to another holder account&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addBindings&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _keyWallet2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;getbindings-function&quot;&gt;&lt;code&gt;getBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; for the &lt;code&gt;_account&lt;&#x2F;code&gt; in a &lt;code&gt;struct&lt;&#x2F;code&gt; format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AccountHolderBindings&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; firstWallet&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; secondWallet&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AccountHolderBindings&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;h4 id=&quot;resetbindings-function&quot;&gt;&lt;code&gt;resetBindings&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; This function is helpful when one of the two &lt;code&gt;keyWallets&lt;&#x2F;code&gt; is compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, the function resets the &lt;code&gt;keyWallets&lt;&#x2F;code&gt; for the &lt;code&gt;holder&lt;&#x2F;code&gt; account. MUST fire the &lt;code&gt;AccountResetBinding&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resetBindings&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;safefallback-function&quot;&gt;&lt;code&gt;safeFallback&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; This function is helpful when the &lt;code&gt;holder&lt;&#x2F;code&gt; account is compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function transfers all the tokens from the &lt;code&gt;holder&lt;&#x2F;code&gt; account to the other &lt;code&gt;keyWallet&lt;&#x2F;code&gt; and MUST fire the &lt;code&gt;SafeFallbackActivated&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowtransfer-function&quot;&gt;&lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function is called before a &lt;code&gt;transferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; functions are called.&lt;&#x2F;p&gt;
&lt;p&gt;It allows to transfer a tokenId, for a specific time frame, to a specific address.&lt;&#x2F;p&gt;
&lt;p&gt;If the tokenId is 0 then there will be no restriction on the tokenId.
If the time is 0 then there will be no restriction on the time.
If the to address is zero address then there will be no restriction on the to address.
Or if &lt;code&gt;_anyToken&lt;&#x2F;code&gt; is &lt;code&gt;true&lt;&#x2F;code&gt;, regardless of the other params, it allows any token, whenever, to anyone to be transferred of the holder.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire &lt;code&gt;AccountEnabledTransfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt; for a holder or if the owner of the &lt;code&gt;_tokenId&lt;&#x2F;code&gt; is different than the &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _anyToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;gettransferablefunds-function&quot;&gt;&lt;code&gt;getTransferableFunds&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the transfer conditions for the &lt;code&gt;_account&lt;&#x2F;code&gt; in a &lt;code&gt;struct&lt;&#x2F;code&gt; format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; anyToken&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTransferableFunds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TransferConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowapproval-function&quot;&gt;&lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;Called from a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;, this function is called before &lt;code&gt;approve&lt;&#x2F;code&gt; or &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; functions are called.&lt;&#x2F;p&gt;
&lt;p&gt;It allows the &lt;code&gt;holder&lt;&#x2F;code&gt; for a specific amount of &lt;code&gt;_time&lt;&#x2F;code&gt; to do an &lt;code&gt;approve&lt;&#x2F;code&gt; or &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; and limit the number of transfers the spender is allowed to do through &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt; (0 - unlimited number of transfers in the allowance limit).&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire &lt;code&gt;AccountEnabledApproval&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if the sender is not a &lt;code&gt;keyWallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _time&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;getapprovalconditions-function&quot;&gt;&lt;code&gt;getApprovalConditions&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function returns the approval conditions in a struct format. Where &lt;code&gt;time&lt;&#x2F;code&gt; is the &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; until the &lt;code&gt;approve&lt;&#x2F;code&gt; or &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; functions can be called, and &lt;code&gt;numberOfTransfers&lt;&#x2F;code&gt; is the number of transfers the spender will be allowed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; numberOfTransfers&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApprovalConditions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ApprovalConditions&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transferfrom-function&quot;&gt;&lt;code&gt;transferFrom&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function transfers from &lt;code&gt;_from&lt;&#x2F;code&gt; address to &lt;code&gt;_to&lt;&#x2F;code&gt; address the &lt;code&gt;_tokenId&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;p&gt;Each time a spender calls the function the contract subtracts and checks if the number of allowed transfers of that spender has reached 0,
and when that happens, the approval is revoked using a set approval for all to &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender is not the owner or is not approved to transfer the &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_from&lt;&#x2F;code&gt; address is not the owner of the &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;or if the sender is a secure account and it has not allowed for transfer this &lt;code&gt;_tokenId&lt;&#x2F;code&gt; through &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;safetransferfrom-function&quot;&gt;&lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function transfers from &lt;code&gt;_from&lt;&#x2F;code&gt; address to &lt;code&gt;_to&lt;&#x2F;code&gt; address the &lt;code&gt;_tokenId&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender is not the owner or is not approved to transfer the &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_from&lt;&#x2F;code&gt; address is not the owner of the &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;or if the sender is a secure account and it has not allowed for transfer this &lt;code&gt;_tokenId&lt;&#x2F;code&gt; through &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;safetransferfrom-function-with-data-parameter&quot;&gt;&lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function, with data parameter&lt;&#x2F;h4&gt;
&lt;p&gt;This works identically to the other function with an extra data parameter, except this function just sets data to &quot;&quot;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;approve-function&quot;&gt;&lt;code&gt;approve&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function allows &lt;code&gt;_to&lt;&#x2F;code&gt; account to transfer the &lt;code&gt;_tokenId&lt;&#x2F;code&gt; from the sender account.&lt;&#x2F;p&gt;
&lt;p&gt;The function also limits the &lt;code&gt;_to&lt;&#x2F;code&gt; account to the specific number of transfers set in the &lt;code&gt;ApprovalConditions&lt;&#x2F;code&gt; for that &lt;code&gt;holder&lt;&#x2F;code&gt; account. If the value is &lt;code&gt;0&lt;&#x2F;code&gt; then the &lt;code&gt;_spender&lt;&#x2F;code&gt; can transfer multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;The function MUST fire an &lt;code&gt;Approval&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;If the function is called again it overrides the number of transfers allowed with &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;, set in &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender is not the current NFT owner, or an authorized operator of the current owner&lt;&#x2F;li&gt;
&lt;li&gt;the NFT owner is secured and has not called &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_time&lt;&#x2F;code&gt;, set in the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function, has elapsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;setapprovalforall-function&quot;&gt;&lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; function&lt;&#x2F;h4&gt;
&lt;p&gt;The function enables or disables approval for another account &lt;code&gt;_operator&lt;&#x2F;code&gt; to manage all of sender assets.&lt;&#x2F;p&gt;
&lt;p&gt;The function also limits the &lt;code&gt;_to&lt;&#x2F;code&gt; account to the specific number of transfers set in the &lt;code&gt;ApprovalConditions&lt;&#x2F;code&gt; for that &lt;code&gt;holder&lt;&#x2F;code&gt; account. If the value is &lt;code&gt;0&lt;&#x2F;code&gt; then the &lt;code&gt;_spender&lt;&#x2F;code&gt; can transfer multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;The function Emits an &lt;code&gt;Approval&lt;&#x2F;code&gt; event indicating the updated allowance.&lt;&#x2F;p&gt;
&lt;p&gt;If the function is called again it overrides the number of transfers allowed with &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;, set in &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The function SHOULD &lt;code&gt;revert&lt;&#x2F;code&gt; if:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the sender account is secured and has not called &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_spender&lt;&#x2F;code&gt; is a zero address (&lt;code&gt;0x0&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;or if the &lt;code&gt;_time&lt;&#x2F;code&gt;, set in the &lt;code&gt;allowApproval&lt;&#x2F;code&gt; function, has elapsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC721&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;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The intent from individual technical decisions made during the development of &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; focused on maintaining consistency and backward compatibility with ERC-721s, all the while offering self-custodial security features to the user. It was important that &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; inherited all of ERC-721s characteristics to comply with requirements found in dApps which use non-fungible tokens on their platform. In doing so, it allowed for flawless backward compatibility to take place and gave the user the choice to decide if they want their &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; to act with &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-3&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. We wanted to ensure that wide-scale implementation and adoption of &lt;strong&gt;NFKBTs&lt;&#x2F;strong&gt; could take place immediately, without the greater collective needing to adapt and make changes to the already flourishing decentralized ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;For developers and users alike, the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; functions both return bools on success and revert on failures. This decision was done purposefully, to keep consistency with the already familiar ERC-721. Additional technical decisions related to self-custodial security features are broken down and located within the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#security-considerations&quot;&gt;Security Considerations&lt;&#x2F;a&gt; section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; are designed to be backward-compatible with existing token standards and wallets. Existing tokens and wallets will continue to function as normal, and will not be affected by the implementation of &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;assets&#x2F;README&#x2F;&quot;&gt;assets&lt;&#x2F;a&gt; directory has all the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;.&#x2F;assets&#x2F;test&#x2F;kbt721.js&quot;&gt;tests&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Average Gas used (&lt;em&gt;GWEI&lt;&#x2F;em&gt;):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;addBindings&lt;&#x2F;code&gt; - 155,096&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resetBindings&lt;&#x2F;code&gt; - 30,588&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;safeFallback&lt;&#x2F;code&gt; - 72,221 (depending on how many NFTs the holder has)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;allowTransfer&lt;&#x2F;code&gt; - 50,025&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;allowApproval&lt;&#x2F;code&gt; - 44,983&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation is located in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;assets&#x2F;README&#x2F;&quot;&gt;assets&lt;&#x2F;a&gt; directory. There&#x27;s also a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;.&#x2F;assets&#x2F;Contract%20Interactions%20diagram.svg&quot;&gt;diagram&lt;&#x2F;a&gt; with the contract interactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; were designed with security in mind every step of the way. Below are some design decisions that were rigorously discussed and thought through during the development process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-5&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: When calling the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; function for an &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt;, the user must input 2 wallets that will then act as &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-3&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-3&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. They are added simultaneously to reduce user fees, minimize the chance of human error and prevent a pitfall scenario. If the user had the ability to add multiple wallets it would not only result in additional fees and avoidable confusion but would enable a potentially disastrous &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; situation to occur. For this reason, all &lt;strong&gt;KBT&#x27;s&lt;&#x2F;strong&gt; work under a 3-wallet system when security features are activated.&lt;&#x2F;p&gt;
&lt;p&gt;Typically if a wallet is compromised, the non-fungible assets within are at risk. With &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; there are two different functions that can be called from a &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-6&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; depending on which wallet has been compromised.&lt;&#x2F;p&gt;
&lt;p&gt;Scenario: &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-3&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised, call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt;: This function was created in the event that the owner believes the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-4&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. It can also be used if the owner losses access to the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;. In this scenario, the user has the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; from one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-7&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; are then redirected from the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; to the other &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By redirecting the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; it prevents a single point of failure. If an attacker were to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#safefallback-function&quot;&gt;safeFallback&lt;&#x2F;a&gt; and the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; redirected to the &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-8&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; that called the function, they would gain access to all the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Scenario: &lt;strong&gt;Key Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-9&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised, call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;: This function was created in the event that the owner believes &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-4&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-4&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; has been compromised. It can also be used if the owner losses access to one of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-10&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. In this instance, the user has the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;, removing the bound &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; and resetting the security features. The &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; will now function as a traditional ERC-721 until &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#addbindings-function&quot;&gt;addBindings&lt;&#x2F;a&gt; is called again and a new set of &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; are added.&lt;&#x2F;p&gt;
&lt;p&gt;The reason why &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-5&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-5&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; are required to call the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; function is because a &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-5&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; having the ability to call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt; could result in an immediate loss of &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;. The attacker would only need to gain access to the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; and call &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#resetbindings-function&quot;&gt;resetBindings&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the scenario that 2 of the 3 wallets have been compromised, there is nothing the owner of the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; can do if the attack is malicious. However, by allowing 1 wallet to be compromised, holders of non-fungible tokens built using the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; standard are given a second chance, unlike other current standards.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function is in place to guarantee a &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-2&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, but can also have &lt;strong&gt;Default Values&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-2&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; set by a dApp to emulate &lt;strong&gt;Default Behaviors&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-6&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; of a traditional ERC-721. It enables the user to highly specify the type of transfer they are about to conduct, whilst simultaneously allowing the user to unlock all the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; to anyone for an unlimited amount of time. The desired security is completely up to the user.&lt;&#x2F;p&gt;
&lt;p&gt;This function requires 4 parameters to be filled and different combinations of these result in different levels of security;&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 1 &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-2&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: This is the ID of the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; that will be spent on a transfer.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 2 &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-2&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of blocks the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; can be transferred starting from the current block timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 3 &lt;code&gt;_address&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-2&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The destination the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; will be sent to.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 4 &lt;code&gt;_anyToken&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-11-2&quot;&gt;&lt;a href=&quot;#fn-11&quot;&gt;11&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: This is a boolean value. When false, the &lt;code&gt;transferFrom&lt;&#x2F;code&gt; function takes into consideration Parameters 1, 2 and 3. If the value is true, the &lt;code&gt;transferFrom&lt;&#x2F;code&gt; function will revert to a &lt;strong&gt;Default Behavior&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-4&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the same as a traditional ERC-721.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowtransfer-function&quot;&gt;allowTransfer&lt;&#x2F;a&gt; function requires &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-6&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-6&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and enables the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-7&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to conduct a &lt;code&gt;transferFrom&lt;&#x2F;code&gt; within the previously specified parameters. These parameters were added in order to provide additional security by limiting the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; in case it was compromised without the user&#x27;s knowledge.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function provides extra security when allowing on-chain third parties to use your &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt; on your behalf. This is especially useful when a user is met with common malicious attacks e.g. draining dApp.&lt;&#x2F;p&gt;
&lt;p&gt;This function requires 2 parameters to be filled and different combinations of these result in different levels of security;&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 1 &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-2&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of blocks that the approval of a third-party service can take place, starting from the current block timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;Parameter 2 &lt;code&gt;_numberOfTransfers_&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-2&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;: The number of transactions a third-party service can conduct on the user&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6809&#x2F;#allowapproval-function&quot;&gt;allowApproval&lt;&#x2F;a&gt; function requires &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-15-7&quot;&gt;&lt;a href=&quot;#fn-15&quot;&gt;14&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-16-7&quot;&gt;&lt;a href=&quot;#fn-16&quot;&gt;15&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and enables the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-8&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to allow a third-party service by using the &lt;code&gt;approve&lt;&#x2F;code&gt; function. These parameters were added to provide extra security when granting permission to a third-party that uses assets on the user&#x27;s behalf. Parameter 1, &lt;code&gt;_time&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-12-3&quot;&gt;&lt;a href=&quot;#fn-12&quot;&gt;12&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, is a limitation to when the &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; can &lt;code&gt;approve&lt;&#x2F;code&gt; a third-party service. Parameter 2, &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-13-3&quot;&gt;&lt;a href=&quot;#fn-13&quot;&gt;13&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, is a limitation to the number of transactions the approved third-party service can conduct on the user&#x27;s behalf before revoking approval.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;The &lt;strong&gt;Key Wallet&#x2F;s&lt;&#x2F;strong&gt; refers to &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; or &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; which can call the &lt;code&gt;safeFallback&lt;&#x2F;code&gt;, &lt;code&gt;resetBindings&lt;&#x2F;code&gt;, &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; and &lt;code&gt;allowApproval&lt;&#x2F;code&gt; functions. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-7&quot;&gt;↩7&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-8&quot;&gt;↩8&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-9&quot;&gt;↩9&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-10&quot;&gt;↩10&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Safe Transfer&lt;&#x2F;strong&gt; is when 1 of the &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; safely approved the use of the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-2-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;The &lt;strong&gt;Holding Wallet&lt;&#x2F;strong&gt; refers to the wallet containing the &lt;strong&gt;NFKBT&#x27;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-7&quot;&gt;↩7&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-3-8&quot;&gt;↩8&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Default Behavior&#x2F;s&lt;&#x2F;strong&gt; refers to behavior&#x2F;s present in the preexisting non-fungible ERC-721 standard. &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-4-4&quot;&gt;↩4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;The number of crypto scam reports the United States Federal Trade Commission received, from January 2021 through March 2022. &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;The amount stolen via crypto scams according to the United States Federal Trade Commission, from January 2021 through March 2022. &lt;a href=&quot;#fr-6-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;A &lt;strong&gt;Default Value&#x2F;s&lt;&#x2F;strong&gt; refer to a value&#x2F;s that emulates the non-fungible ERC-721 &lt;strong&gt;Default Behavior&#x2F;s&lt;&#x2F;strong&gt;. &lt;a href=&quot;#fr-7-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-7-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;The &lt;code&gt;_tokenId&lt;&#x2F;code&gt; represents the ID of the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; intended to be spent. &lt;a href=&quot;#fr-8-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-8-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-9&quot;&gt;
&lt;p&gt;The &lt;code&gt;_time&lt;&#x2F;code&gt; in &lt;code&gt;allowTransfer&lt;&#x2F;code&gt; represents the number of blocks a &lt;code&gt;transferFrom&lt;&#x2F;code&gt; can take place in. &lt;a href=&quot;#fr-9-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-9-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-10&quot;&gt;
&lt;p&gt;The &lt;code&gt;_address&lt;&#x2F;code&gt; represents the address that the &lt;strong&gt;NFKBT&lt;&#x2F;strong&gt; will be sent to. &lt;a href=&quot;#fr-10-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-10-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-11&quot;&gt;
&lt;p&gt;The &lt;code&gt;_anyToken&lt;&#x2F;code&gt; is a bool that can be set to true or false. &lt;a href=&quot;#fr-11-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-11-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-12&quot;&gt;
&lt;p&gt;The &lt;code&gt;_time&lt;&#x2F;code&gt; in &lt;code&gt;allowApproval&lt;&#x2F;code&gt; represents the number of blocks an &lt;code&gt;approve&lt;&#x2F;code&gt; can take place in. &lt;a href=&quot;#fr-12-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-12-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-12-3&quot;&gt;↩3&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-13&quot;&gt;
&lt;p&gt;The &lt;code&gt;_numberOfTransfers&lt;&#x2F;code&gt; is the number of transfers a third-party entity can conduct via &lt;code&gt;transferFrom&lt;&#x2F;code&gt; on the user&#x27;s behalf. &lt;a href=&quot;#fr-13-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-13-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-13-3&quot;&gt;↩3&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-15&quot;&gt;
&lt;p&gt;The &lt;code&gt;_keyWallet1&lt;&#x2F;code&gt; is 1 of the 2 &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; set when calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function. &lt;a href=&quot;#fr-15-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-15-7&quot;&gt;↩7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-16&quot;&gt;
&lt;p&gt;The &lt;code&gt;_keyWallet2&lt;&#x2F;code&gt; is 1 of the 2 &lt;strong&gt;Key Wallets&lt;&#x2F;strong&gt; set when calling the &lt;code&gt;addBindings&lt;&#x2F;code&gt; function. &lt;a href=&quot;#fr-16-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-2&quot;&gt;↩2&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-3&quot;&gt;↩3&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-4&quot;&gt;↩4&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-5&quot;&gt;↩5&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-6&quot;&gt;↩6&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-16-7&quot;&gt;↩7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-14&quot;&gt;
&lt;p&gt;A &lt;em&gt;PoS&lt;&#x2F;em&gt; protocol, Proof-of-Stake protocol, is a cryptocurrency consensus mechanism for processing transactions and creating new blocks in a blockchain. &lt;a href=&quot;#fr-14-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>SELFDESTRUCT only in same transaction</title>
        <published>2023-03-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Guillaume Ballet</name><uri>https://github.com/gballet</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6780/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/deactivate-selfdestruct-except-where-it-occurs-in-the-same-transaction-in-which-a-contract-was-created/13539" />
        

        <id>https://wg-eips.ritovision.com/6780/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:6780"
            label="EIP-6780" />
        

        
        

        
        <summary type="html">SELFDESTRUCT will recover all funds to the target but not delete the account, except when called in the same transaction as creation</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6780/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP changes the functionality of the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode. The new functionality will be only to send all Ether in the account to the target, except that the current behaviour is preserved when &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is called in the same transaction a contract was created.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode requires large changes to the state of an account, in particular removing all code and storage. This will not be possible in the future with Verkle trees: Each account will be stored in many different account keys, which will not be obviously connected to the root account.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP implements this change. Applications that only use &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; to retrieve funds will still work. Applications that only use &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; in the same transaction as they created a contract will also continue to work without any changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The behaviour of &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is changed in the following way:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;When &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is executed in a transaction that is not the same as the contract calling &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; was created:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The current execution frame halts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; does not delete any data (including storage keys, code, or the account itself).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; transfers the entire account balance to the target.&lt;&#x2F;li&gt;
&lt;li&gt;Note that if the target is the same as the contract calling &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; there is no net change in balances.  Unlike the prior specification, Ether will not be burnt in this case.&lt;&#x2F;li&gt;
&lt;li&gt;Note that no refund is given since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3529&#x2F;&quot;&gt;EIP-3529&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Note that the rules of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; regarding &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; remain unchanged.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is executed in the same transaction as the contract was created:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; continues to behave as it did prior to this EIP, this includes the following actions
&lt;ul&gt;
&lt;li&gt;The current execution frame halts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; deletes data as previously specified.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; transfers the entire account balance to the target&lt;&#x2F;li&gt;
&lt;li&gt;The account balance of the contact calling &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is set to &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Note that if the target is the same as the contract calling &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; that Ether will be burnt.&lt;&#x2F;li&gt;
&lt;li&gt;Note that no refund is given since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3529&#x2F;&quot;&gt;EIP-3529&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Note that the rules of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; regarding &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; remain unchanged.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A contract is considered created at the beginning of a create transaction or when a CREATE series operation begins execution (CREATE, CREATE2, and other operations that deploy contracts in the future).  If a balance exists at the contract&#x27;s new address it is still considered to be a contract creation.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode remains deprecated as specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6049&#x2F;&quot;&gt;EIP-6049&lt;&#x2F;a&gt;. Any use in newly deployed contracts is strongly discouraged even if this new behaviour is taken into account, and future changes to the EVM might further reduce the functionality of the opcode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Getting rid of the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode has been considered in the past, and there are currently no strong reasons to use it. This EIP implements a behavior that will attempt to leave some common uses of &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; working, while reducing the complexity of the change on EVM implementations that would come from contract versioning.&lt;&#x2F;p&gt;
&lt;p&gt;Handling the account creation and contract creation as two distinct and possibly separate events is needed for use cases such as counterfactual accounts.  By allowing the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; to delete the account at contract creation time it will not result in stubs of counterfactually instantiated contracts that never had any on-chain state other than a balance prior to the contract creation. These accounts would never have any storage and thus the trie updates to delete the account would be limited to the account node, which is the same impact a regular transfer of ether would have.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP requires a hard fork, since it modifies consensus rules.&lt;&#x2F;p&gt;
&lt;p&gt;Contracts that depended on re-deploying contracts at the same address using &lt;code&gt;CREATE2&lt;&#x2F;code&gt; (after a &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;) will no longer function properly if the created contract does not call &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; within the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Previously it was possible to burn ether by calling &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; targeting the executing contract as the beneficiary.  If the contract existed prior to the transaction the ether will not be burned.  If the contract was newly created in the transaction the ether will be burned, as before.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases for this EIP can be found in the Execution Spec Tests suite &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;tree&#x2F;1983444bbe1a471886ef7c0e82253ffe2a4053e1&#x2F;tests&#x2F;cancun&#x2F;eip6780_selfdestruct&quot;&gt;&lt;code&gt;eip6780_selfdestruct&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The following applications of &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; will be broken and applications that use it in this way are not safe anymore:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Where &lt;code&gt;CREATE2&lt;&#x2F;code&gt; is used to redeploy a contract in the same place in order to make a contract upgradable. This is not supported anymore and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;&quot;&gt;ERC-2535&lt;&#x2F;a&gt; or other types of proxy contracts should be used instead.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Where a contract depended on burning Ether via a &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; with the contract as beneficiary, in a contract not created within the same transaction.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Revert creation in case of collision</title>
        <published>2023-03-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Renan Rodrigues de Souza</name><uri>https://github.com/RenanSouza2</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/684/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-revert-on-address-collision/13442" />
        

        <id>https://wg-eips.ritovision.com/684/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:684"
            label="EIP-684" />
        

        
        

        
        <summary type="html">Revert contract creation if address already has code</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/684/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP causes contract creation to throw an error when attempted at an address with pre-existing code. This prevents an attack consisting of deploying contract code and later changing the code arbitrarily by &quot;creating&quot; an account at that existing address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;If a contract creation is attempted due to a creation transaction, the &lt;code&gt;CREATE&lt;&#x2F;code&gt; opcode, the &lt;code&gt;CREATE2&lt;&#x2F;code&gt; opcode, or any other reason, and the destination address already has either a nonzero nonce, or a nonzero code length, then the creation MUST throw as if the first byte in the init code were an invalid opcode. This change MUST apply retroactively for all existing blocks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;One of the core tenets of smart contracts is that their code will not change. However with sufficient computing power an attacker can change the code stored in an address to any other code, steal funds or execute other malicious activity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is an execution layer upgrade, and so it requires a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Given a genesis allocation of&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Address : 0xd0bBEc6D2c628b7e2E6D5556daA14a5181b604C5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Balance : 1000000000000000000, &#x2F;&#x2F; 1 ether&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce   : 0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;code    : &amp;quot;&amp;quot;,&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;Address : 0x7658771dc6Af74a3d2F8499D349FF9c1a0DF8826,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Balance : 0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce   : 1,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Code    : &amp;quot;0xB0B0FACE&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A contract created in the first transaction from EOA &lt;code&gt;0xd0bBEc6...&lt;&#x2F;code&gt; (&lt;code&gt;227bcc6959669226360814723ed739f1214201584b6a27409dfb8228b8be5f59&lt;&#x2F;code&gt;), with no salt, should revert.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is a security upgrade: it enforces the immutability of deployed code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multi-redeemable NFTs</title>
        <published>2023-02-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>RE:DREAMER Lab</name><email>dev@redreamer.io</email>
	</author>
	
	<author>
		<name>Archie Chang</name><uri>https://github.com/ArchieR7</uri><email>archie@redreamer.io</email>
	</author>
	
	<author>
		<name>Kai Yu</name><uri>https://github.com/chihkaiyu</uri><email>kai@redreamer.io</email>
	</author>
	
	<author>
		<name>Yonathan Randyanto</name><uri>https://github.com/Randyanto</uri><email>randy@redreamer.io</email>
	</author>
	
	<author>
		<name>Boyu Chu</name><uri>https://github.com/chuboyu</uri><email>boyu@redreamer.io</email>
	</author>
	
	<author>
		<name>Boxi Li</name><uri>https://github.com/boxi79</uri><email>boxi@redreamer.io</email>
	</author>
	
	<author>
		<name>Jason Cheng</name><uri>https://github.com/JasonCheng0729</uri><email>jason@redreamer.io</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6672/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6672-multi-redeemable-nfts/13276" />
        

        <id>https://wg-eips.ritovision.com/6672/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6672"
            label="ERC-6672" />
        

        
        

        
        <summary type="html">An extension of ERC-721 which enables an NFT to be redeemed in multiple scenarios for either a physical or digital object</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6672/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes an extension to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard for Non-Fungible Tokens (NFTs) to enable multi-redeemable NFTs. Redemption provides a means for NFT holders to demonstrate ownership and eligibility of their NFT, which in turn enables them to receive a physical or digital item. This extension would allow an NFT to be redeemed in multiple scenarios and maintain a record of its redemption status on the blockchain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The motivation behind our proposed NFT standard is to provide a more versatile and flexible solution compared to existing standards, allowing for multi-redeemable NFTs. Our proposed NFT standard enables multi-redeemable NFTs, allowing them to be redeemed in multiple scenarios for different campaigns or events, thus unlocking new possibilities for commerce use cases and breaking the limitation of one-time redemption per NFT.&lt;&#x2F;p&gt;
&lt;p&gt;One use case for an NFT that can be redeemed multiple times in various scenarios is a digital concert ticket. The NFT could be redeemed for access to the online concert and then again for exclusive merchandise, a meet and greet with the artist, or any exclusive commerce status that is bound to the NFT. Each redemption could represent a unique experience or benefit for the NFT holder.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;redeem-and-cancel-functions&quot;&gt;Redeem and Cancel Functions&lt;&#x2F;h3&gt;
&lt;p&gt;An operator SHALL only make an update to the redemption created by itself. Therefore, the &lt;code&gt;redeem()&lt;&#x2F;code&gt; and &lt;code&gt;cancel()&lt;&#x2F;code&gt; functions do not have an &lt;code&gt;_operator&lt;&#x2F;code&gt; parameter, and the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; address MUST be used as the &lt;code&gt;_operator&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;redemption-flag-key-value-pairs&quot;&gt;Redemption Flag Key-Value Pairs&lt;&#x2F;h3&gt;
&lt;p&gt;The combination of &lt;code&gt;_operator&lt;&#x2F;code&gt;, &lt;code&gt;_tokenId&lt;&#x2F;code&gt;, and &lt;code&gt;_redemptionId&lt;&#x2F;code&gt; MUST be used as the key in the redemption flag key-value pairs, whose value can be accessed from the &lt;code&gt;isRedeemed()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Every contract compliant with this EIP MUST implement &lt;code&gt;ERC6672&lt;&#x2F;code&gt; and &lt;code&gt;ERC721&lt;&#x2F;code&gt; interfaces.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-6672 Multi-Redeemable NFT Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6672&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x4dddf83f.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6672&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when an NFT is redeemed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; redeemer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _memo&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when a redemption is canceled.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Cancel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;      uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;      bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _memo&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check whether an NFT is already used for redemption or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the operator of the redemption platform.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for a redemption.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an NFT is already redeemed or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isRedeemed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; List the redemptions created by the given operator for the given NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the operator of the redemption platform.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; List&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of redemptions of speficic `_operator` and `_tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRedemptionIds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Redeem an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier created by the operator for a redemption.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to redeem.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _memo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _memo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Cancel a redemption&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The redemption to cancel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to cancel the redemption.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _memo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cancel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _redemptionId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _memo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;metadata-extension&quot;&gt;Metadata Extension&lt;&#x2F;h3&gt;
&lt;p&gt;The key format for the &lt;code&gt;redemptions&lt;&#x2F;code&gt; key-value pairs MUST be standardized as &lt;code&gt;operator-tokenId-redemptionId&lt;&#x2F;code&gt;, where &lt;code&gt;operator&lt;&#x2F;code&gt; is the operator wallet address, &lt;code&gt;tokenId&lt;&#x2F;code&gt; is  the identifier of the token that has been redeemed, and &lt;code&gt;redemptionId&lt;&#x2F;code&gt; is the redemption identifier. The value of the key &lt;code&gt;operator-tokenId-redemptionId&lt;&#x2F;code&gt; is an object that contains the &lt;code&gt;status&lt;&#x2F;code&gt; and &lt;code&gt;description&lt;&#x2F;code&gt; of the redemption.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Redemption status, i.e. &lt;code&gt;status&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The redemption status can have a more granular level, rather than just being a flag with a &lt;code&gt;true&lt;&#x2F;code&gt; or &lt;code&gt;false&lt;&#x2F;code&gt; value. For instance, in cases of physical goods redemption, we may require the redemption status to be either &lt;code&gt;redeemed&lt;&#x2F;code&gt;, &lt;code&gt;paid&lt;&#x2F;code&gt;, or &lt;code&gt;shipping&lt;&#x2F;code&gt;. It is RECOMMENDED to use a string enum that is comprehensible by both the operator and the marketplace or any other parties that want to exhibit the status of the redemption.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Description of the redemption, i.e. &lt;code&gt;description&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;description&lt;&#x2F;code&gt; SHOULD be used to provide more details about the redemption, such as information about the concert ticket, a detailed description of the action figures, and more.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;strong&gt;metadata extension&lt;&#x2F;strong&gt; is OPTIONAL for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;&quot;&gt;ERC-6672&lt;&#x2F;a&gt; smart contracts (see &quot;caveats&quot;, below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-6672 Multi-Redeemable Token Standard, optional metadata extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6672&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6672Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC721Metadata &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A distinct Uniform Resource Identifier (URI) for a given asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  3986. The URI may point to a JSON file that conforms to the &amp;quot;ERC-6672&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Metadata JSON Schema&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the &quot;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;&quot;&gt;ERC-6672&lt;&#x2F;a&gt; Metadata JSON Schema&quot; referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;redemptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;operator-tokenId-redemptionId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The status of a redemption. Enum type can be used to represent the redemption status, such as redeemed, shipping, paid.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the object that has been redeemed for an NFT, such as the name of an action figure series name or the color of the product.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;key-choices-for-redemption-flag-and-status&quot;&gt;Key Choices for Redemption Flag and Status&lt;&#x2F;h3&gt;
&lt;p&gt;The combination of &lt;code&gt;_operator&lt;&#x2F;code&gt;, &lt;code&gt;_tokenId&lt;&#x2F;code&gt;, and &lt;code&gt;_redemptionId&lt;&#x2F;code&gt; is chosen as the key because it provides a clear and unique identifier for each redemption transaction.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Operator wallet address, i.e. &lt;code&gt;_operator&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s possible that there are more than one party who would like to use the same NFT for redemption. For example, MisterPunks NFTs are eligible to be redeemed for both Event-X and Event-Y tickets, and each event&#x27;s ticket redemption is handled by a different operator.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Token identifier, i.e. &lt;code&gt;_tokenId&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each NFT holder will have different redemption records created by the same operator. Therefore, it&#x27;s important to use token identifier as one of the keys.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Redemption identifier, i.e. &lt;code&gt;_redemptionId&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using &lt;code&gt;_redemptionId&lt;&#x2F;code&gt; as one of the keys enables NFT holders to redeem the same NFT to the same operator in multiple campaigns. For example, Operator-X has 2 campaigns, i.e. campaign A and campaign B, and both campaigns allow for MisterPunks NFTs to be redeemed for physical action figures. Holder of MisterPunk #7 is eligible for redemption in both campaigns and each redemption is recorded with the same &lt;code&gt;_operator&lt;&#x2F;code&gt; and &lt;code&gt;_tokenId&lt;&#x2F;code&gt;, but with different &lt;code&gt;_redemptionId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The reference implementation of Multi-Redeemable NFT can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC6672.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;An incorrect implementation of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;&quot;&gt;ERC-6672&lt;&#x2F;a&gt; could potentially allow an unauthorized operator to access redemption flags owned by other operators, creating a security risk. As a result, an unauthorized operator could cancel the redemption process managed by other operators. Therefore, it is crucial for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;&quot;&gt;ERC-6672&lt;&#x2F;a&gt; implementations to ensure that only the operator who created the redemption, identified using &lt;code&gt;msg.sender&lt;&#x2F;code&gt;, can update the redemption flag using the &lt;code&gt;redeem()&lt;&#x2F;code&gt; and &lt;code&gt;cancel()&lt;&#x2F;code&gt; functions. It is also recommended to isolate the &lt;code&gt;redeem()&lt;&#x2F;code&gt; and &lt;code&gt;cancel()&lt;&#x2F;code&gt; functions from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; approval models.&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6672&#x2F;&quot;&gt;ERC-6672&lt;&#x2F;a&gt; token is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, so wallets and smart contracts capable of storing and handling standard &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; tokens will not face the risk of asset loss caused by incompatible standard implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Signature Validation for Predeploy Contracts</title>
        <published>2023-02-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ivo Georgiev</name><uri>https://github.com/Ivshti</uri>
	</author>
	
	<author>
		<name>Agustin Aguilar</name><uri>https://github.com/Agusx1211</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6492/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6492-signature-validation-for-pre-deploy-contracts/12903" />
        

        <id>https://wg-eips.ritovision.com/6492/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6492"
            label="ERC-6492" />
        

        
        

        
        <summary type="html">A way to verify a signature when the account is a smart contract that has not been deployed yet</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6492/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Contracts can sign verifiable messages via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, if the contract is not deployed yet, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; verification is impossible, as you can&#x27;t call the &lt;code&gt;isValidSignature&lt;&#x2F;code&gt; function on said contract.&lt;&#x2F;p&gt;
&lt;p&gt;We propose a standard way for any contract or off-chain actor to verify whether a signature on behalf of a given counterfactual contract (that is not deployed yet) is valid. This standard way extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the rising popularity of account abstraction, we often find that the best user experience for contract wallets is to defer contract deployment until the first user transaction, therefore not burdening the user with an additional deploy step before they can use their account. However, at the same time, many dApps expect signatures, not only for interactions, but also just for logging in.&lt;&#x2F;p&gt;
&lt;p&gt;As such, contract wallets have been limited in their ability to sign messages before their de-facto deployment, which is often done on the first transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, not being able to sign messages from counterfactual contracts has always been a limitation of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;The words &quot;validation&quot; and &quot;verification&quot; are used interchangeably.&lt;&#x2F;p&gt;
&lt;p&gt;Quoting &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;,&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;isValidSignature&lt;&#x2F;code&gt; can call arbitrary methods to validate a given signature, which could be context dependent (e.g. time based or state based), EOA dependent (e.g. signers authorization level within smart wallet), signature scheme Dependent (e.g. ECDSA, multisig, BLS), etc.&lt;&#x2F;p&gt;
&lt;p&gt;This function should be implemented by contracts which desire to sign messages (e.g. smart contract wallets, DAOs, multisignature wallets, etc.) Applications wanting to support contract signatures should call this method if the signer is a contract.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We use the same &lt;code&gt;isValidSignature&lt;&#x2F;code&gt; function, but we add a new wrapper signature format, that signing contracts MAY use before they&#x27;re deployed, in order to allow support for verification.&lt;&#x2F;p&gt;
&lt;p&gt;The signature verifier MUST perform a contract deployment before attempting to call &lt;code&gt;isValidSignature&lt;&#x2F;code&gt; if the wrapper signature format is detected.&lt;&#x2F;p&gt;
&lt;p&gt;The wrapper format is detected by checking if the signature ends in &lt;code&gt;magicBytes&lt;&#x2F;code&gt;, which MUST be defined as &lt;code&gt;0x6492649264926492649264926492649264926492649264926492649264926492&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is RECOMMENDED to use this ERC with CREATE2 contracts, as their deploy address is always predictable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;signer-side&quot;&gt;Signer side&lt;&#x2F;h3&gt;
&lt;p&gt;The signing contract will normally be a contract wallet, but it could be any contract that implements &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; and is deployed counterfactually.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the contract is deployed, produce a normal &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; signature&lt;&#x2F;li&gt;
&lt;li&gt;If the contract is not deployed yet, wrap the signature as follows: &lt;code&gt;concat(abi.encode((create2Factory, factoryCalldata, originalERC1271Signature), (address, bytes, bytes)), magicBytes)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;If the contract is deployed but not ready to verify using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;, wrap the signature as follows: &lt;code&gt;concat(abi.encode((prepareTo, prepareData, originalERC1271Signature), (address, bytes, bytes)), magicBytes)&lt;&#x2F;code&gt;; &lt;code&gt;prepareTo&lt;&#x2F;code&gt; and &lt;code&gt;prepareData&lt;&#x2F;code&gt; must contain the necessary transaction that will make the contract ready to verify using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; (e.g. a call to &lt;code&gt;migrate&lt;&#x2F;code&gt; or &lt;code&gt;update&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that we&#x27;re passing &lt;code&gt;factoryCalldata&lt;&#x2F;code&gt; instead of &lt;code&gt;salt&lt;&#x2F;code&gt; and &lt;code&gt;bytecode&lt;&#x2F;code&gt;. We do this in order to make verification compliant with any factory interface. We do not need to calculate the address based on  &lt;code&gt;create2Factory&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;salt&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;bytecode&lt;&#x2F;code&gt;, because &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; verification presumes we already know the account address we&#x27;re verifying the signature for.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;verifier-side&quot;&gt;Verifier side&lt;&#x2F;h3&gt;
&lt;p&gt;Full signature verification MUST be performed in the following order:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;check if the signature ends with magic bytes, in which case do an &lt;code&gt;eth_call&lt;&#x2F;code&gt; to a multicall contract that will call the factory first with the &lt;code&gt;factoryCalldata&lt;&#x2F;code&gt; and deploy the contract if it isn&#x27;t already deployed; Then, call &lt;code&gt;contract.isValidSignature&lt;&#x2F;code&gt; as usual with the unwrapped signature&lt;&#x2F;li&gt;
&lt;li&gt;check if there&#x27;s contract code at the address. If so perform &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; verification as usual by invoking &lt;code&gt;isValidSignature&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;if the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; verification fails, and the deploy call to the &lt;code&gt;factory&lt;&#x2F;code&gt; was skipped due to the wallet already having code, execute the &lt;code&gt;factoryCalldata&lt;&#x2F;code&gt; transaction and try &lt;code&gt;isValidSignature&lt;&#x2F;code&gt; again&lt;&#x2F;li&gt;
&lt;li&gt;if there is no contract code at the address, try &lt;code&gt;ecrecover&lt;&#x2F;code&gt; verification&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;We believe that wrapping the signature in a way that allows to pass the deploy data is the only clean way to implement this, as it&#x27;s completely contract agnostic, but also easy to verify.&lt;&#x2F;p&gt;
&lt;p&gt;The wrapper format ends in &lt;code&gt;magicBytes&lt;&#x2F;code&gt;, which ends with a &lt;code&gt;0x92&lt;&#x2F;code&gt;, which makes it is impossible for it to collide with a valid &lt;code&gt;ecrecover&lt;&#x2F;code&gt; signature if packed in the &lt;code&gt;r,s,v&lt;&#x2F;code&gt; format, as &lt;code&gt;0x92&lt;&#x2F;code&gt; is not a valid value for &lt;code&gt;v&lt;&#x2F;code&gt;. To avoid collisions with normal &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;, &lt;code&gt;magicBytes&lt;&#x2F;code&gt; itself is also quite long (&lt;code&gt;bytes32&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The order to ensure correct verification is based on the following rules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;checking for &lt;code&gt;magicBytes&lt;&#x2F;code&gt; MUST happen before the usual &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; check in order to allow counterfactual signatures to be valid even after contract deployment&lt;&#x2F;li&gt;
&lt;li&gt;checking for &lt;code&gt;magicBytes&lt;&#x2F;code&gt; MUST happen before &lt;code&gt;ecrecover&lt;&#x2F;code&gt; in order to avoid trying to verify a counterfactual contract signature via &lt;code&gt;ecrecover&lt;&#x2F;code&gt; if such is clearly identifiable&lt;&#x2F;li&gt;
&lt;li&gt;checking &lt;code&gt;ecrecover&lt;&#x2F;code&gt; MUST NOT happen before &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; verification, because a contract may use a signature format that also happens to be a valid &lt;code&gt;ecrecover&lt;&#x2F;code&gt; signature for an EOA with a different address. One such example is a contract that&#x27;s a wallet controlled by said EOA.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can&#x27;t determine the reason why a signature was encoded with a &quot;deploy prefix&quot; when the corresponding wallet already has code. It could be due to the signature being created before the contract was deployed, or it could be because the contract was deployed but not ready to verify signatures yet. As such, we need to try both options.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC is backward compatible with previous work on signature validation, including &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; and allows for easy verification of all signature types, including EOA signatures and typed data (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-erc-6492-for-regular-contract-signatures&quot;&gt;Using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6492&#x2F;&quot;&gt;ERC-6492&lt;&#x2F;a&gt; for regular contract signatures&lt;&#x2F;h3&gt;
&lt;p&gt;The wrapper format described in this ERC can be used for all contract signatures, instead of plain &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;. This provides several advantages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;allows quick recognition of the signature type: thanks to the magic bytes, you can immediately know whether the signature is a contract signature without checking the blockchain&lt;&#x2F;li&gt;
&lt;li&gt;allows recovery of address: you can get the address only from the signature using &lt;code&gt;create2Factory&lt;&#x2F;code&gt; and &lt;code&gt;factoryCalldata&lt;&#x2F;code&gt;, just like &lt;code&gt;ecrecover&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Below you can find an implementation of a universal verification contract that can be used both on-chain and off-chain, intended to be deployed as a singleton. It can validate signatures signed with this ERC, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; and traditional &lt;code&gt;ecrecover&lt;&#x2F;code&gt;. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; is also supported by extension, as we validate the final digest (&lt;code&gt;_hash&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; As per ERC-1271&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC1271Wallet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; magicValue&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1271Revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6492DeployFailed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UniversalSigValidator&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC6492_DETECTION_SUFFIX &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x6492649264926492649264926492649264926492649264926492649264926492&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC1271_SUCCESS &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x1626ba7e&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSigImpl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; allowSideEffects&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tryPrepare&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span&gt; contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;code&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; sigToValidate&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The order here is strictly defined in https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6492&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - ERC-6492 suffix check and verification first, while being permissive in case the contract is already deployed; if the contract is deployed we will check the sig against the deployed version, this allows 6492 signatures to still be validated while taking into account potential key rotation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - ERC-1271 verification if there&amp;#39;s contract code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - finally, ecrecover&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isCounterfactual &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; ERC6492_DETECTION_SUFFIX&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;isCounterfactual&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      address&lt;&#x2F;span&gt;&lt;span&gt; create2Factory&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; factoryCalldata&lt;&#x2F;span&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;span&gt;create2Factory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; factoryCalldata&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sigToValidate&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; tryPrepare&lt;&#x2F;span&gt;&lt;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; err&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; create2Factory&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;factoryCalldata&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6492DeployFailed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;err&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;z-keyword&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&gt;      sigToValidate &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Try ERC-1271 verification&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;isCounterfactual &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      try&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC1271Wallet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sigToValidate&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; magicValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; isValid &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; magicValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; ERC1271_SUCCESS&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; retry, but this time assume the prefix is a prepare call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;isValid &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;tryPrepare &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;          return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSigImpl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; allowSideEffects&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; isCounterfactual &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;allowSideEffects&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if the call had side effects we need to return the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; result using a `revert` (to undo the state changes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;           mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; isValid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;           revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; isValid&lt;&#x2F;span&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;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; err&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; retry, but this time assume the prefix is a prepare call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;tryPrepare &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; contractCodeLen &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;          return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSigImpl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; allowSideEffects&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1271Revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;err&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ecrecover verification&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;SignatureValidator#recoverSigner: invalid signature length&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;SignatureValidator: invalid signature v value&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ecrecover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _signer&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSigWithSideEffects&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSigImpl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSig&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSigImpl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isValid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; isValid&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    catch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; in order to avoid side effects from the contract getting deployed, the entire call will revert with a single byte result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      uint&lt;&#x2F;span&gt;&lt;span&gt; len &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;len &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; all other errors are simply forwarded, but in custom formats so that nothing else can revert with a single byte in the call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; assembly&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this is a helper so we can perform validation in a single eth_call without pre-deploying a singleton&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ValidateSigOffchain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span&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&gt;    UniversalSigValidator validator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UniversalSigValidator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isValidSig &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; validator&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSigWithSideEffects&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;      mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; isValidSig&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;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;h3 id=&quot;on-chain-validation&quot;&gt;On-chain validation&lt;&#x2F;h3&gt;
&lt;p&gt;For on-chain validation, you could use two separate methods:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UniversalSigValidator.isValidSig(_signer, _hash, _signature)&lt;&#x2F;code&gt;: returns a bool of whether the signature is valid or not; this is reentrancy-safe&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;UniversalSigValidator.isValidSigWithSideEffects(_signer, _hash, _signature)&lt;&#x2F;code&gt;: this is equivalent to the former - it is not reentrancy-safe but it is more gas-efficient in certain cases&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Both methods may revert if the underlying calls revert.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;off-chain-validation&quot;&gt;Off-chain validation&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ValidateSigOffchain&lt;&#x2F;code&gt; helper allows you to perform the universal validation in one &lt;code&gt;eth_call&lt;&#x2F;code&gt;, without any pre-deployed contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s example of how to do this with the &lt;code&gt;ethers&lt;&#x2F;code&gt; library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; isValidSignature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&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&gt;  data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ethers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;concat&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    validateSigOffchainBytecode&lt;&#x2F;span&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;span class=&quot;z-keyword&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ethers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;AbiCoder&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&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&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&gt;}&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 may also use a library to perform the universal signature validation, such as Ambire&#x27;s &lt;code&gt;signature-validator&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same considerations as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; apply.&lt;&#x2F;p&gt;
&lt;p&gt;However, deploying a contract requires a &lt;code&gt;CALL&lt;&#x2F;code&gt; rather than a &lt;code&gt;STATICCALL&lt;&#x2F;code&gt;, which introduces reentrancy concerns. This is mitigated in the reference implementation by having the validation method always revert if there are side-effects, and capturing its actual result from the revert data. For use cases where reentrancy is not a concern, we have provided the &lt;code&gt;isValidSigWithSideEffects&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, it is likely that this ERC will be more frequently used for off-chain validation, as in many cases, validating a signature on-chain presumes the wallet has been already deployed.&lt;&#x2F;p&gt;
&lt;p&gt;One out-of-scope security consideration worth mentioning is whether the contract is going to be set-up with the correct permissions at deploy time, in order to allow for meaningful signature verification. By design, this is up to the implementation, but it&#x27;s worth noting that thanks to how CREATE2 works, changing the bytecode or contructor callcode in the signature will not allow you to escalate permissions as it will change the deploy address and therefore make verification fail.&lt;&#x2F;p&gt;
&lt;p&gt;It must be noted that contract accounts can dynamically change their methods of authentication. This issue is mitigated by design in this EIP - even when validating counterfactual signatures, if the contract is already deployed, we will still call it, checking against the current live version of the contract.&lt;&#x2F;p&gt;
&lt;p&gt;As per usual with signatures, replay protection should be implemented in most use cases. This proposal adds an extra dimension to this, because it may be possible to validate a signature that has been rendered invalid (by changing the authorized keys) on a different network as long as 1) the signature was valid at the time of deployment 2) the wallet can be deployed with the same factory address&#x2F;bytecode on this different network.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Minimal Transferable NFT detection interface</title>
        <published>2023-01-31T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Francesco Sullo</name><uri>https://github.com/sullof</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6454/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/minimalistic-transferable-interface/12517" />
        

        <id>https://wg-eips.ritovision.com/6454/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6454"
            label="ERC-6454" />
        

        
        

        
        <summary type="html">A minimal extension to identify the transferability of Non-Fungible Tokens.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6454/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Minimalistic Transferable interface for Non-Fungible Tokens standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; by introducing the ability to identify whether an NFT can be transferred or not.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal introduces the ability to prevent a token from being transferred from their owner, making them bound to the externally owned account, abstracted account, smart contract or token that owns it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability to prevent the tokens from being transferred introduces new possibilities of NFT utility and evolution.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal is designed in a way to be as minimal as possible in order to be compatible with any usecases that wish to utilize this proposal.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP introduces new utilities for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; based tokens in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6454&#x2F;#verifiable-attribution&quot;&gt;Verifiable attribution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6454&#x2F;#immutable-properties&quot;&gt;Immutable properties&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;verifiable-attribution&quot;&gt;Verifiable attribution&lt;&#x2F;h3&gt;
&lt;p&gt;Personal achievements can be represented by non-fungible tokens. These tokens can be used to represent a wide range of accomplishments, including scientific advancements, philanthropic endeavors, athletic achievements, and more. However, if these achievement-indicating NFTs can be easily transferred, their authenticity and trustworthiness can be called into question. By binding the NFT to a specific account, it can be ensured that the account owning the NFT is the one that actually achieved the corresponding accomplishment. This creates a secure and verifiable record of personal achievements that can be easily accessed and recognized by others in the network. The ability to verify attribution helps to establish the credibility and value of the achievement-indicating NFT, making it a valuable asset that can be used as a recognition of the holder&#x27;s accomplishments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;immutable-properties&quot;&gt;Immutable properties&lt;&#x2F;h3&gt;
&lt;p&gt;NFT properties are a critical aspect of non-fungible tokens, serving to differentiate them from one another and establish their scarcity. Centralized control of NFT properties by the issuer, however, can undermine the uniqueness of these properties.&lt;&#x2F;p&gt;
&lt;p&gt;By tying NFTs to specific properties, the original owner is ensured that the NFT will always retain these properties and its uniqueness.&lt;&#x2F;p&gt;
&lt;p&gt;In a blockchain game that employs non-transferable NFTs to represent skills or abilities, each skill would be a unique and permanent asset tied to a specific player or token. This would ensure that players retain ownership of the skills they have earned and prevent them from being traded or sold to other players. This can increase the perceived value of these skills, enhancing the player experience by allowing for greater customization and personalization of characters.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-6454 Minimalistic Non-Transferable interface for NFTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6454&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x91a6262f.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6454&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to check whether the given token is transferable or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If this function returns `false`, the transfer of the token MUST revert execution.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the tokenId does not exist, this method MUST revert execution, unless the token is being checked for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  minting.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `from` parameter MAY be used to also validate the approval of the token for transfer, but anyone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  interacting with this function SHOULD NOT rely on it as it is not mandated by the proposal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address from which the token is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to which the token is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; value indicating whether the given token is transferable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTransferable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In order to determine whether a token is transferable or not in general, the function SHOULD return the appropriate boolean value when passing the &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt; address as the &lt;code&gt;to&lt;&#x2F;code&gt; and &lt;code&gt;from&lt;&#x2F;code&gt; parameter.&lt;&#x2F;p&gt;
&lt;p&gt;The general transferability of a token should not be affected by the ability to mint the token (value of &lt;code&gt;from&lt;&#x2F;code&gt; parameter is &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;) and the ability to burn the token (value of &lt;code&gt;to&lt;&#x2F;code&gt; parameter is &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;If the general transferability of token is &lt;code&gt;false&lt;&#x2F;code&gt;, any kind of transfer of the token, save minting and burning, MUST revert execution.&lt;&#x2F;p&gt;
&lt;p&gt;In order to determine whether a token is mintable, the exception SHOULD be made to allow the &lt;code&gt;tokenId&lt;&#x2F;code&gt; parameter for a token that does not exist. Additionally the &lt;code&gt;from&lt;&#x2F;code&gt; parameter SHOULD be &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt; and the &lt;code&gt;to&lt;&#x2F;code&gt; parameter SHOULD NOT be &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In order to determine whether a token is burnable, the &lt;code&gt;from&lt;&#x2F;code&gt; parameter SHOULD NOT be &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt; and the &lt;code&gt;to&lt;&#x2F;code&gt; parameter SHOULD be &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers MAY choose to validate the approval of the token for transfer by the &lt;code&gt;from&lt;&#x2F;code&gt; parameter, but anyone interacting with this function SHOULD NOT rely on it as it is not mandated by the proposal. This means that the &lt;code&gt;from&lt;&#x2F;code&gt; parameter in such implementations validates the initiator of the transaction rather than the owner from which the token is being transferred (which can either be the owner of the token or the operator allowed to transfer the token).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Should we propose another (Non-)Transferable NFT proposal given the existence of existing ones, some even final, and how does this proposal compare to them?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
This proposal aims to provide the minimum necessary specification for the implementation of non-transferable NFTs, we feel none of the existing proposals have presented the minimal required interface. Unlike other proposals that address the same issue, this proposal requires fewer methods in its specification, providing a more streamlined solution.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is there no event marking the token as Non-Transferable in this interface?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The token can become non-transferable either at its creation, after being marked as non-transferable, or after a certain condition is met. This means that some cases of tokens becoming non-transferable cannot emit an event, such as if the token becoming non-transferable is determined by a block number. Requiring an event to be emitted upon the token becoming non-transferable is not feasible in such cases.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should the transferability state management function be included in this proposal?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
A function that marks a token as non-transferable or releases the binding is referred to as the transferability management function. To maintain the objective of designing an agnostic minimal transferable proposal, we have decided not to specify the transferability management function. This allows for a variety of custom implementations that require the tokens to be non-transferable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why should this be an EIP if it only contains one method?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
One could argue that since the core of this proposal is to only prevent ERC-721 tokens to be transferred, this could be done by overriding the transfer function. While this is true, the only way to assure that the token is non-transferable before the smart contract execution, is for it to have the transferable interface.&lt;br &#x2F;&gt;
This also allows for smart contract to validate whether the token is not transferable and not attempt transferring it as this would result in failed transactions and wasted gas.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we include the most straightforward method possible that only accepts a &lt;code&gt;tokenId&lt;&#x2F;code&gt; parameter?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The initial version of the proposal contained a method that only accepted a &lt;code&gt;tokenId&lt;&#x2F;code&gt; parameter. This method would return a boolean value indicating whether the token is transferable. However, the fact that the token can be non-transferable for different reasons was brought up throughout the discussion. This is why the method was changed to accept additional parameters, allowing for a more flexible implementation. Additionally, we kept the original method’s functionality by specifying the methodology on how to achieve the same result (by passing the &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt; address as the &lt;code&gt;to&lt;&#x2F;code&gt; and &lt;code&gt;from&lt;&#x2F;code&gt; parameters).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;What is the best user experience for frontend?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The best user experience for the front end is having a single method that checks whether the token is transferable. This method should handle both cases of transferability, general and conditional.&lt;br &#x2F;&gt;
The front end should also be able to handle the case where the token is not transferable and the transfer is attempted. This can be done by checking the return value of the transfer function, which will be false if the token is not transferable. If the token would just be set as non-transferable, without a standardized interface to check whether the token is transferable, the only way to validate transferability would be to attempt a gas calculation and check whether the transaction would revert. This is a bad user experience and should be avoided.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we mandate that the &lt;code&gt;isTransferable&lt;&#x2F;code&gt; validates approvals as well?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
We considered specifying that the &lt;code&gt;from&lt;&#x2F;code&gt; parameter represents the initiator of the token transfer. This would mean that the &lt;code&gt;from&lt;&#x2F;code&gt; would validate whether the address is the owner of the token or approved to transfer it. While this might be beneficial, we ultimately decided to make it optional.&lt;br &#x2F;&gt;
As this proposal aims to be the minimal possible implementation and the approvals are already standardized, we feel that &lt;code&gt;isTransferable&lt;&#x2F;code&gt; can be used in conjunction with the approvals to validate whether the given address can initiate the transfer or not.&lt;br &#x2F;&gt;
Additionally, mandating the validation of approvals would incur higher gas consumption as additional checks would be required to validate the transferability.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Minimalistic Non-Transferable token standard is fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and with the robust tooling available for implementations of ERC-721 as well as with the existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6454&#x2F;.&#x2F;assets&#x2F;test&#x2F;transferable.ts&quot;&gt;&lt;code&gt;transferable.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-6454&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6454&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;mocks&#x2F;ERC721TransferableMock.sol&quot;&gt;&lt;code&gt;ERC721TransferableMock.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; apply: hidden logic may be present in any of the functions, including burn, add asset, accept asset, and more.&lt;&#x2F;p&gt;
&lt;p&gt;A smart contract can implement the proposal interface but returns fraudulent values, i.e., returning &lt;code&gt;false&lt;&#x2F;code&gt; for &lt;code&gt;isTransferable&lt;&#x2F;code&gt; when the token is transferable. Such a contract would trick other contracts into thinking that the token is non-transferable when it is transferable. If such a contract exists, we suggest not interacting with it. Much like fraudulent &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; smart contracts, it is not possible to prevent such contracts from existing. We suggest that you verify all of the external smart contracts you interact with and not interact with contracts you do not trust.&lt;&#x2F;p&gt;
&lt;p&gt;Since the transferability state can change over time, verifying that the state of the token is transferable before interacting with it is essential. Therefore, a dApp, marketplace, or wallet implementing this interface should verify the state of the token every time the token is displayed.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Stealth Meta-Address Registry</title>
        <published>2023-01-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Matt Solomon</name><uri>https://github.com/mds1</uri>
	</author>
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	<author>
		<name>Ben DiFrancesco</name><uri>https://github.com/apbendi</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Gary Ghayrat</name><uri>https://github.com/garyghayrat</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6538/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/stealth-meta-address-registry/12888" />
        

        <id>https://wg-eips.ritovision.com/6538/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6538"
            label="ERC-6538" />
        

        
        

        
        <summary type="html">A canonical contract for entities to register stealth meta-addresses directly or through a third party using signatures.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6538/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines a standardized way of storing and retrieving an entity&#x27;s stealth meta-address, by extending &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5564&#x2F;&quot;&gt;ERC-5564&lt;&#x2F;a&gt;. An entity may register their stealth meta-address directly. A third party can also register on behalf of an entity using a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;EIP-1271&lt;&#x2F;a&gt; signature. Once registered, the stealth meta-address for the entity can be retrieved by any smart contract or user. One can use the stealth meta-address with &lt;code&gt;generateStealthAddress&lt;&#x2F;code&gt; specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5564&#x2F;&quot;&gt;ERC-5564&lt;&#x2F;a&gt; to send assets to the generated stealth address without revealing the entity&#x27;s address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The standardization of stealth address generation holds the potential to greatly enhance the privacy capabilities of Ethereum by enabling the recipient of a transfer to remain anonymous when receiving an asset. By introducing a central smart contract for users to store their stealth meta-addresses, EOAs and contracts can programmatically engage in stealth interactions using a variety of stealth address schemes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;This contract defines an &lt;code&gt;ERC6538Registry&lt;&#x2F;code&gt; that stores the stealth meta-address for entities. These entities may be identified by an address, ENS name, or other identifier. This MUST be a singleton contract, with one instance per chain.&lt;&#x2F;p&gt;
&lt;p&gt;The contract is specified below. A one byte integer is used to identify the stealth address scheme. This integer is used to differentiate between different stealth address schemes. This ERC outlines schemeId &lt;code&gt;1&lt;&#x2F;code&gt; as the SECP256k1 curve cryptographic scheme with view tags, as specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5564&#x2F;&quot;&gt;ERC-5564&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `ERC6538Registry` contract to map accounts to their stealth meta-address. See&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; [ERC-6538](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6538) to learn more.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6538Registry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an invalid signature is provided to `registerKeysOnBehalf`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6538Registry__InvalidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Next nonce expected from `user` to use when signing for `registerKeysOnBehalf`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `registrant` may be a standard 160-bit address or any other identifier.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `schemeId` is an integer identifier for the stealth address scheme.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; registrant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; schemeId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; stealthMetaAddressOf&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A nonce used to ensure a signature can only be used once.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `registrant` is the user address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `nonce` will be incremented after each valid `registerKeysOnBehalf` call.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; registrant &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; nonceOf&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-712 type hash used in `registerKeysOnBehalf`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC6538REGISTRY_ENTRY_TYPE_HASH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Erc6538RegistryEntry(uint256 schemeId,bytes stealthMetaAddress,uint256 nonce)&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The chain ID where this contract is initially deployed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; immutable&lt;&#x2F;span&gt;&lt;span&gt; INITIAL_CHAIN_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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The domain separator used in this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; immutable&lt;&#x2F;span&gt;&lt;span&gt; INITIAL_DOMAIN_SEPARATOR&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a registrant updates their stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that registered the stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; [ERC-5564](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-5564) bases the format for stealth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; meta-addresses on [ERC-3770](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3770) and specifies them as:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   st:&amp;lt;shortName&amp;gt;:0x&amp;lt;spendingPubKey&amp;gt;:&amp;lt;viewingPubKey&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The chain (`shortName`) is implicit based on the chain the `ERC6538Registry` is deployed on,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; therefore this `stealthMetaAddress` is just the compressed `spendingPubKey` and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `viewingPubKey` concatenated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StealthMetaAddressSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a registrant increments their nonce.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that incremented the nonce.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newNonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new nonce value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NonceIncremented&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newNonce&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    INITIAL_CHAIN_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    INITIAL_DOMAIN_SEPARATOR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _computeDomainSeparator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the caller&amp;#39;s stealth meta-address for the given scheme ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address to register.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerKeys&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    stealthMetaAddressOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;schemeId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StealthMetaAddressSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the `registrant`&amp;#39;s stealth meta-address for the given scheme ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the registrant.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A signature from the `registrant` authorizing the registration.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address to register.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Supports both EOA signatures and EIP-1271 signatures.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts if the signature is invalid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerKeysOnBehalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&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 class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; dataHash&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; recoveredAddress&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;    unchecked&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      dataHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-string&quot;&gt;          &amp;quot;\x19\x01&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 class=&quot;z-entity z-name&quot;&gt;          DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ERC6538REGISTRY_ENTRY_TYPE_HASH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&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&gt;              nonceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;registrant&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      bytes32&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      bytes32&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      uint8&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;      assembly&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;memory-safe&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x20&lt;&#x2F;span&gt;&lt;span&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&gt;        s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x40&lt;&#x2F;span&gt;&lt;span&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&gt;        v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; byte&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x60&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      recoveredAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ecrecover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;recoveredAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; recoveredAddress &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;          &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            IERC1271&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;registrant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dataHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;              !=&lt;&#x2F;span&gt;&lt;span&gt; IERC1271&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6538Registry__InvalidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stealthMetaAddressOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;registrant&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;schemeId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StealthMetaAddressSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;registrant&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increments the nonce of the sender to invalidate existing signatures.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; incrementNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;    unchecked&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      nonceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NonceIncremented&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nonceOf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the domain separator used in this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The domain separator is re-computed if there&amp;#39;s a chain fork.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; INITIAL_CHAIN_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; INITIAL_DOMAIN_SEPARATOR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _computeDomainSeparator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Computes the domain separator for this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _computeDomainSeparator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;      abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-string&quot;&gt;          &amp;quot;EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC6538Registry&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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;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;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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface of the ERC1271 standard signature validation method for contracts as defined&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; in https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1271[ERC-1271].&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC1271&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Should return whether the signature provided is valid for the provided data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hash of the data to be signed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Signature byte array associated with _data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; magicValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interface for this contract is defined below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for calling the `ERC6538Registry` contract to map accounts to their stealth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; meta-address. See [ERC-6538](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6538) to learn more.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6538Registry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when an invalid signature is provided to `registerKeysOnBehalf`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6538Registry__InvalidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a registrant updates their stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that registered the stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; [ERC-5564](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-5564) bases the format for stealth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; meta-addresses on [ERC-3770](https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3770) and specifies them as:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   st:&amp;lt;shortName&amp;gt;:0x&amp;lt;spendingPubKey&amp;gt;:&amp;lt;viewingPubKey&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The chain (`shortName`) is implicit based on the chain the `ERC6538Registry` is deployed on,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; therefore this `stealthMetaAddress` is just the `spendingPubKey` and `viewingPubKey`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; concatenated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StealthMetaAddressSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a registrant increments their nonce.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that incremented the nonce.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newNonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new nonce value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NonceIncremented&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newNonce&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the caller&amp;#39;s stealth meta-address for the given scheme ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address to register.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerKeys&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the `registrant`&amp;#39;s stealth meta-address for the given scheme ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the registrant.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identifier corresponding to the applied stealth address scheme, e.g. 1 for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; secp256k1, as specified in ERC-5564.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A signature from the `registrant` authorizing the registration.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth meta-address to register.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Supports both EOA signatures and EIP-1271 signatures.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reverts if the signature is invalid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerKeysOnBehalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signature&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Increments the nonce of the sender to invalidate existing signatures.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; incrementNonce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the domain separator used in this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the stealth meta-address for the given `registrant` and `schemeId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; stealthMetaAddressOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the EIP-712 type hash used in `registerKeysOnBehalf`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6538REGISTRY_ENTRY_TYPE_HASH&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the nonce of the given `registrant`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nonceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; registrant&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;deployment-method&quot;&gt;Deployment Method&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ERC6538Registry&lt;&#x2F;code&gt; contract is deployed at &lt;code&gt;0x6538E6bf4B0eBd30A8Ea093027Ac2422ce5d6538&lt;&#x2F;code&gt; using &lt;code&gt;CREATE2&lt;&#x2F;code&gt; via the deterministic deployer at &lt;code&gt;0x4e59b44847b379578588920ca78fbf26c0b4956c&lt;&#x2F;code&gt; with a salt of &lt;code&gt;0x7cac4e512b1768c627c9e711c7a013f1ad0766ef5125c59fb7161dade58da078&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Having a central smart contract for registering stealth meta-addresses has several benefits:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It guarantees interoperability with other smart contracts, as they can easily retrieve and utilize the registered stealth meta-addresses. This enables applications such as ENS or Gnosis Safe to use that information and integrate stealth addresses into their services.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It ensures that users are not dependent on off-chain sources to retrieve a user&#x27;s stealth meta-address.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Registration of a stealth meta-address in this contract provides a standard way for users to communicate that they&#x27;re ready to participate in stealth interactions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;By deploying the registry as a singleton contract, multiple projects can access the same set of stealth meta-addresses, contributing to improved standardization.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is fully backward compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;You can find an implementation of the &lt;code&gt;ERC6538Registry&lt;&#x2F;code&gt; contract &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6538&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC6538Registry.sol&quot;&gt;here&lt;&#x2F;a&gt; and the interface &lt;code&gt;IERC6538Registry.sol&lt;&#x2F;code&gt; &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6538&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;interfaces&#x2F;IERC6538Registry.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;In the event of a compromised private key, the registrant should promptly un-register from the stealth key registry to prevent loss of future funds sent to the compromised account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Public Non-Fungible Token Emote Repository</title>
        <published>2023-01-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6381/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6381-emotable-extension-for-non-fungible-tokens/12710" />
        

        <id>https://wg-eips.ritovision.com/6381/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6381"
            label="ERC-6381" />
        

        
        

        
        <summary type="html">React to any Non-Fungible Tokens using Unicode emojis.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6381/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Public Non-Fungible Token Emote Repository standard provides an enhanced interactive utility for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; by allowing NFTs to be emoted at.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal introduces the ability to react to NFTs using Unicode standardized emoji in a public non-gated repository smart contract that is accessible at the same address in all of the networks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability for anyone to interact with an NFT introduces an interactive aspect to owning an NFT and unlocks feedback-based NFT mechanics.&lt;&#x2F;p&gt;
&lt;p&gt;This ERC introduces new utilities for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; based tokens in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;#interactivity&quot;&gt;Interactivity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;#feedback-based-evolution&quot;&gt;Feedback based evolution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;#valuation&quot;&gt;Valuation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;interactivity&quot;&gt;Interactivity&lt;&#x2F;h3&gt;
&lt;p&gt;The ability to emote on an NFT introduces the aspect of interactivity to owning an NFT. This can either reflect the admiration for the emoter (person emoting to an NFT) or can be a result of a certain action performed by the token&#x27;s owner. Accumulating emotes on a token can increase its uniqueness and&#x2F;or value.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;feedback-based-evolution&quot;&gt;Feedback based evolution&lt;&#x2F;h3&gt;
&lt;p&gt;Standardized on-chain reactions to NFTs allow for feedback based evolution.&lt;&#x2F;p&gt;
&lt;p&gt;Current solutions are either proprietary or off-chain and therefore subject to manipulation and distrust. Having the ability to track the interaction on-chain allows for trust and objective evaluation of a given token. Designing the tokens to evolve when certain emote thresholds are met incentivizes interaction with the token collection.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;valuation&quot;&gt;Valuation&lt;&#x2F;h3&gt;
&lt;p&gt;Current NFT market heavily relies on previous values the token has been sold for, the lowest price of the listed token and the scarcity data provided by the marketplace. There is no real time indication of admiration or desirability of a specific token. Having the ability for users to emote to the tokens adds the possibility of potential buyers and sellers gauging the value of the token based on the impressions the token has collected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-6381 Emotable Extension for Non-Fungible Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6381&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xd9fac55a.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6381&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;is IERC165&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the token with the specified ID has been emoted to or that the reaction has been revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event MUST only be emitted if the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that emoted or revoked the reaction to the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract containing the token being emoted to or having the reaction revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; on&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether the token was emoted to (`true`) or if the reaction has been revoked (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Emoted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; on&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the number of emotes for a specific emoji on a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection containing the token being checked for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to check for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of emotes with the emoji on the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; emoteCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the number of emotes for a specific emoji on a set of tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being checked for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens to check for emoji count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; An&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of numbers of emotes with the emoji on the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkEmoteCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the information on whether the specified address has used a specific emoji on a specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account we are checking for a reaction to a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract containing the token being checked for emoji reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being checked for emoji reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ASCII emoji code being checked for reaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; boolean value indicating whether the `emoter` has used the `emoji` on the token (`true`) or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasEmoterUsedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the information on whether the specified addresses have used specific emojis on specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the accounts we are checking for reactions to tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collection smart contracts containing the tokens being checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  for emoji reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being checked for emoji reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of the ASCII emoji codes being checked for reactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; An&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of boolean values indicating whether the `emoter`s has used the `emoji`s on the tokens (`true`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  or not (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; haveEmotersUsedEmotes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the message to be signed by the `emoter` in order for the reaction to be submitted by someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the collection smart contract containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; message to be signed by the `emoter` in order for the reaction to be submitted by someone else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; prepareMessageToPresignEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadline&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get multiple messages to be signed by the `emoter` in order for the reaction to be submitted by someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collection smart contracts containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An arrau of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of UNIX timestamps of the deadlines for the signatures to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of messages to be signed by the `emoter` in order for the reaction to be submitted by someone else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkPrepareMessagesToPresignEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadlines&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; emote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on multiple tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to emote or undo an emote on someone else&amp;#39;s behalf.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the `deadline` has passed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the recovered address is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that presigned the emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the collection smart contract containing the token being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IDs of the token being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unicode identifier of the emoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `v` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `r` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `s` value of an ECDSA signature of the message obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; presignedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to bulk emote or undo an emote on someone else&amp;#39;s behalf.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Does nothing if attempting to set a pre-existent state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the `Emoted` event is the state of the emote is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the `deadline` has passed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert if the recovered address is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the accounts that presigned the emotes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses of the collections containing the tokens being emoted at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens being emoted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of unicode identifiers of the emojis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; states&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of boolean values signifying whether to emote (`true`) or undo (`false`) emote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `v` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `r` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `s` values of an ECDSA signatures of the messages obtained via `prepareMessageToPresignEmote`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bulkPresignedEmote&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emoters&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; collections&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; emojis&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; states&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadlines&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;message-format-for-presigned-emotes&quot;&gt;Message format for presigned emotes&lt;&#x2F;h3&gt;
&lt;p&gt;The message to be signed by the &lt;code&gt;emoter&lt;&#x2F;code&gt; in order for the reaction to be submitted by someone else is formatted as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            collection&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&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&gt;            emoji&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            state&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            deadline&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The values passed when generating the message to be signed are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; - The domain separator of the Emotable repository smart contract&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;collection&lt;&#x2F;code&gt; - Address of the collection containing the token being emoted at&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt; - ID of the token being emoted&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;emoji&lt;&#x2F;code&gt; - Unicode identifier of the emoji&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;state&lt;&#x2F;code&gt; - Boolean value signifying whether to emote (&lt;code&gt;true&lt;&#x2F;code&gt;) or undo (&lt;code&gt;false&lt;&#x2F;code&gt;) emote&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;deadline&lt;&#x2F;code&gt; - UNIX timestamp of the deadline for the signature to be submitted&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; is generated as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;ERC-6381: Public Non-Fungible Token Emote Repository&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 class=&quot;z-string&quot;&gt;            &amp;quot;1&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 class=&quot;z-variable z-language&quot;&gt;            block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each chain, that the Emotable repository smart contract is deployed on, will have a different &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; value due to chain IDs being different.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pre-determined-address-of-the-emotable-repository&quot;&gt;Pre-determined address of the Emotable repository&lt;&#x2F;h3&gt;
&lt;p&gt;The address of the Emotable repository smart contract is designed to resemble the function it serves. It starts with &lt;code&gt;0x311073&lt;&#x2F;code&gt; which is the abstract representation of &lt;code&gt;EMOTE&lt;&#x2F;code&gt;. The address is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x31107354b61A0412E722455A771bC462901668eA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Does the proposal support custom emotes or only the Unicode specified ones?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The proposal only accepts the Unicode identifier which is a &lt;code&gt;bytes4&lt;&#x2F;code&gt; value. This means that while we encourage implementers to add the reactions using standardized emojis, the values not covered by the Unicode standard can be used for custom emotes. The only drawback being that the interface displaying the reactions will have to know what kind of image to render and such additions will probably be limited to the interface or marketplace in which they were made.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should the proposal use emojis to relay the impressions of NFTs or some other method?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The impressions could have been done using user-supplied strings or numeric values, yet we decided to use emojis since they are a well established mean of relaying impressions and emotions.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should the proposal establish an emotable extension or a common-good repository?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Initially we set out to create an emotable extension to be used with any ERC-721 compliant tokens. However, we realized that the proposal would be more useful if it was a common-good repository of emotable tokens. This way, the tokens that can be reacted to are not only the new ones but also the old ones that have been around since before the proposal.&lt;br &#x2F;&gt;
In line with this decision, we decided to calculate a deterministic address for the repository smart contract. This way, the repository can be used by any NFT collection without the need to search for the address on the given chain.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we include only single-action operations, only multi-action operations, or both?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
We&#x27;ve considered including only single-action operations, where the user is only able to react with a single emoji to a single token, but we decided to include both single-action and multi-action operations. This way, the users can choose whether they want to emote or undo emote on a single token or on multiple tokens at once.&lt;br &#x2F;&gt;
This decision was made for the long-term viability of the proposal. Based on the gas cost of the network and the number of tokens in the collection, the user can choose the most cost-effective way of emoting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we add the ability to emote on someone else&#x27;s behalf?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
While we did not intend to add this as part of the proposal when drafting it, we realized that it would be a useful feature for it. This way, the users can emote on behalf of someone else, for example, if they are not able to do it themselves or if the emote is earned through an off-chain activity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How do we ensure that emoting on someone else&#x27;s behalf is legitimate?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
We could add delegates to the proposal; when a user delegates their right to emote to someone else, the delegate can emote on their behalf. However, this would add a lot of complexity and additional logic to the proposal.&lt;br &#x2F;&gt;
Using ECDSA signatures, we can ensure that the user has given their consent to emote on their behalf. This way, the user can sign a message with the parameters of the emote and the signature can be submitted by someone else.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we add chain ID as a parameter when reacting to a token?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
During the course of discussion of the proposal, a suggestion arose that we could add chain ID as a parameter when reacting to a token. This would allow the users to emote on the token of one chain on another chain.&lt;br &#x2F;&gt;
We decided against this as we feel that additional parameter would rarely be used and would add additional cost to the reaction transactions. If the collection smart contract wants to utilize on-chain emotes to tokens they contain, they require the reactions to be recorded on the same chain. Marketplaces and wallets integrating this proposal will rely on reactions to reside in the same chain as well, because if chain ID parameter was supported this would mean that they would need to query the repository smart contract on all of the chains the repository is deployed in order to get the reactions for a given token.&lt;br &#x2F;&gt;
Additionally, if the collection creator wants users to record their reactions on a different chain, they can still direct the users to do just that. The repository does not validate the existence of the token being reacted to, which in theory means that you can react to non-existent token or to a token that does not exist yet. The likelihood of a different collection existing at the same address on another chain is significantly low, so the users can react using the collection&#x27;s address on another chain and it is very unlikely that they will unintentionally react to another collection&#x27;s token.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Emote repository standard is fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and with the robust tooling available for implementations of ERC-721 as well as with the existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;.&#x2F;assets&#x2F;test&#x2F;emotableRepository.ts&quot;&gt;&lt;code&gt;emotableRepository.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-6381&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6381&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;EmotableRepository.sol&quot;&gt;&lt;code&gt;EmotableRepository.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The proposal does not envision handling any form of assets from the user, so the assets should not be at risk when interacting with an Emote repository.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to use ECDSA signatures to emote on someone else&#x27;s behalf introduces the risk of a replay attack, which the format of the message to be signed guards against. The &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; used in the message to be signed is unique to the repository smart contract of the chain it is deployed on. This means that the signature is invalid on any other chain and the Emote repositories deployed on them should revert the operation if a replay attack is attempted.&lt;&#x2F;p&gt;
&lt;p&gt;Another thing to consider is the ability of presigned message reuse. Since the message includes the signature validity deadline, the message can be reused any number of times before the deadline is reached. The proposal only allows for a single reaction with a given emoji to a specific token to be active, so the presigned message can not be abused to increase the reaction count on the token. However, if the service using the repository relies on the ability to revoke the reaction after certain actions, a valid presigned message can be used to re-react to the token. We suggest that the services using the repository in cnjunction with presigned messages use deadlines that invalidate presigned messages after a reasonalby short period of time.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Semantic Soulbound Tokens</title>
        <published>2022-12-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Jessica Chang</name><uri>https://github.com/JessicaChg</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6239/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6239-semantic-soulbound-tokens/12334" />
        

        <id>https://wg-eips.ritovision.com/6239/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6239"
            label="ERC-6239" />
        

        
        

        
        <summary type="html">Adding RDF triples to ERC-5192 token metadata to capture social meaning</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6239/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5192&#x2F;&quot;&gt;ERC-5192&lt;&#x2F;a&gt; by introducing Resource Description Framework (RDF) triples to Soulbound Tokens&#x27; (‘SBTs‘) metadata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A Soulbound Token represents the commitments, credentials, and affiliations of accounts. RDF is a standard data model developed by the World Wide Web Consortium (‘W3C’) and is used to represent information in a structured format. Semantic SBTs are built on existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5192&#x2F;&quot;&gt;ERC-5192&lt;&#x2F;a&gt; standards to include RDF triples in metadata to capture and store the meaning of social metadata as a network of accounts and attributes.&lt;&#x2F;p&gt;
&lt;p&gt;Semantic SBT provides a foundation for publishing, linking, and integrating data from multiple sources, and enables the ability to query and retrieve information across these sources, using inference to uncover new insights from existing social relations. For example, form the on-chain united social graph, assign trusted contacts for social recovery, and supports fair governance.&lt;&#x2F;p&gt;
&lt;p&gt;While the existence of SBTs can create a decentralized social framework, there still needs to specify a common data model to manage the social metadata on-chain in a trustless manner, describing social metadata in an interconnected way, make it easy to be exchanged, integrated and discovered. And to further fuel the boom of the SBTs ecosystem, we need a bottom-up and decentralized way to maintain people’s social identity related information.&lt;&#x2F;p&gt;
&lt;p&gt;Semantic SBTs address this by storing social metadata, attestations, and access permissions on-chain to bootstrap the social identity layer and a linked data layer natively on Ethereum, and bring semantic meanings to the tons of bits of on-chain data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;connectedness&quot;&gt;Connectedness&lt;&#x2F;h3&gt;
&lt;p&gt;Semantic SBTs store social data as RDF triples in the Subject-Predicate-Object format, making it easy to create relationships between accounts and attributes.  RDF is a standard for data interchange used to represent highly interconnected data. Representing data in RDF triples makes it simpler for automated systems to identify, clarify, and connect information.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linked-data&quot;&gt;Linked Data&lt;&#x2F;h3&gt;
&lt;p&gt;Semantic SBTs allow the huge amount of social data on-chain to be available in a standard format (RDF) and be reachable and manageable. The interrelated datasets on-chain can create the linked data layer that allows social data to be mixed, exposed, and shared across different applications, providing a convenient, cheap, and reliable way to retrieve data, regardless of the number of users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;social-identity&quot;&gt;Social Identity&lt;&#x2F;h3&gt;
&lt;p&gt;Semantic SBTs allow people to publish or attest their own identity-related data in a bottom-up and decentralized way, without reliance on any centralized intermediaries while setting every party free. The data is fragmentary in each Semantic SBT and socially interrelated. RDF triples enable various community detection algorithms to be built on top.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal outlines the semantic data modeling of SBTs that allows implementers to model the social relations among Semantic SBTs, especially in the social sector.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The token &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interfaces:
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;’s &lt;code&gt;ERC165&lt;&#x2F;code&gt; (&lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;’s &lt;code&gt;ERC721&lt;&#x2F;code&gt; (&lt;code&gt;0x80ac58cd&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;’s &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; (&lt;code&gt;0x5b5e139f&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5192&#x2F;&quot;&gt;ERC-5192&lt;&#x2F;a&gt;’s &lt;code&gt;ERC5192&lt;&#x2F;code&gt; (&lt;code&gt;0xb45a3c0e&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;rdf-statement&quot;&gt;RDF Statement&lt;&#x2F;h3&gt;
&lt;p&gt;RDF statements come in various formats, we have selected the six most commonly used formats: &lt;code&gt;nt(N-Triples)&lt;&#x2F;code&gt;,&lt;code&gt;ttl(Turtle)&lt;&#x2F;code&gt;,&lt;code&gt;rdf(RDF&#x2F;XML)&lt;&#x2F;code&gt;,&lt;code&gt;rj(RDF&#x2F;JSON)&lt;&#x2F;code&gt;,&lt;code&gt;nq(N-Quads)&lt;&#x2F;code&gt; and &lt;code&gt;trig(TriG)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The complete format of an RDF statement:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rdfStatements = {[format]}&amp;lt;statements&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the following section, fragments surrounded by &lt;code&gt;{}&lt;&#x2F;code&gt; characters are OPTIONAL.&lt;&#x2F;p&gt;
&lt;p&gt;In the following section, fragments surrounded by &lt;code&gt;&amp;lt;&amp;gt;&lt;&#x2F;code&gt; characters are REQUIRED.&lt;&#x2F;p&gt;
&lt;p&gt;format: nt&#x2F;ttl&#x2F;rdf&#x2F;rj&#x2F;nq&#x2F;trig&lt;&#x2F;p&gt;
&lt;p&gt;When no format is selected: statements = [ttl]statements&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nt(n-triples)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;nt&lt;&#x2F;code&gt; uses space to separate the subject, predicate, object of a triple, and a period . to indicate the end of a triple.&lt;&#x2F;p&gt;
&lt;p&gt;The basic structure is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;subject predicate object .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this format, the subject is in the format of IRIREF or BLANK_NODE_LABEL, the predicate is in the format of IRIREF, and the object is in the format of IRIREF, BLANK_NODE_LABEL, or STRING_LITERAL_QUOTE.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&amp;gt; &amp;lt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;02&#x2F;22-rdf-syntax-ns#type&amp;gt; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;User&amp;gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&amp;gt; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;name&amp;gt; &amp;quot;Alice&amp;quot; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ttl(Turtle)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Compared to &lt;code&gt;nt&lt;&#x2F;code&gt;, &lt;code&gt;ttl&lt;&#x2F;code&gt; uses prefixes to simplify the IRIREF format, and the same predicate under the same subject can be merged without repeating it. &quot;a&quot; can be used to represent &lt;code&gt;&amp;lt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;02&#x2F;22-rdf-syntax-ns#type&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@prefix : &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;&amp;gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@prefix p: &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;&amp;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&gt;:user1 a :User;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       p:name ”Alice” .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rdf(RDF&#x2F;XML)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;rdf&lt;&#x2F;code&gt; describes RDF in XML format, using rdf:RDF as the top-level element, and xmlns to describe prefixes. rdf:Description begins describing a node, rdf:about defines the node to be described, and rdf:resource fills in the property value in the format of IRI. If the property value is a string, the property value can be directly written as the text of the property node.&lt;&#x2F;p&gt;
&lt;p&gt;The basic structure is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;RDF&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F; 02&#x2F;22-rdf-syntax-ns#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;about&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;subject&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;predicate&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;predicate&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;object&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;predicate&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;RDF&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;RDF&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F; 02&#x2F;22-rdf-syntax-ns#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity&quot;&gt;           xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;about&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Alice&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;RDF&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rj(RDF&#x2F;JSON)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;rj&lt;&#x2F;code&gt; describes RDF in JSON format. A triple is described as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&amp;quot;subject&amp;quot;:{&amp;quot;predicate&amp;quot;:[object]}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that each root object is a unique primary key and duplicates are not allowed. There will be no duplicate subjects as keys, and there will be no duplicate predicates under a single subject.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;02&#x2F;22-rdf-syntax-ns#type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;User&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nq(N-Quads)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;nq&lt;&#x2F;code&gt; is based on &lt;code&gt;nt&lt;&#x2F;code&gt; but includes a graph label that describes the dataset to which an RDF triple belongs. The graph label can be in the format of IRIREF or BLANK_NODE_LABEL.&lt;&#x2F;p&gt;
&lt;p&gt;The basic structure is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;subject predicate object graphLabel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&amp;gt; &amp;lt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;02&#x2F;22-rdf-syntax-ns#type&amp;gt; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;User&amp;gt; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;graphs&#x2F;example&amp;gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;user1&amp;gt; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;name&amp;gt; &amp;quot;Alice&amp;quot; &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;graphs&#x2F;example&amp;gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;trig(TriG)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;trig&lt;&#x2F;code&gt; is an extension of &lt;code&gt;ttl&lt;&#x2F;code&gt; that includes a graph label to describe the dataset to which an RDF triple belongs. The triple statements are enclosed in curly braces {}.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@prefix : &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;entity&#x2F;&amp;gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@prefix p: &amp;lt;http:&#x2F;&#x2F;example.org&#x2F;property&#x2F;&amp;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&gt;&amp;lt;http:&#x2F;&#x2F;example.org&#x2F;graphs&#x2F;example&amp;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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       :user1 a :User;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              p:name ”Alice” .&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;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the contract events: &lt;code&gt;CreateRDF&lt;&#x2F;code&gt;, &lt;code&gt;UpdateRDF&lt;&#x2F;code&gt;, &lt;code&gt;RemoveRDF&lt;&#x2F;code&gt;, and the &lt;code&gt;rdfOf method&lt;&#x2F;code&gt;, the  &lt;code&gt;rdfStatements&lt;&#x2F;code&gt; is used in &lt;code&gt;ttl&lt;&#x2F;code&gt; format by default. If other formats listed above are used, a format identifier needs to be added for identification.&lt;&#x2F;p&gt;
&lt;p&gt;The format identifier starts with &lt;code&gt;[&lt;&#x2F;code&gt; and ends with &lt;code&gt;]&lt;&#x2F;code&gt; with the format in the middle, i.e., &lt;code&gt;[format]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For example, the &lt;code&gt;rdfStatements&lt;&#x2F;code&gt; in &lt;code&gt;nt&lt;&#x2F;code&gt; format should include the prefix &lt;code&gt;[nt]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[nt]subject predicate object .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Semantic Soulbound Token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xfbafb698&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ISemanticSBT&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when minting a Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for the Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rdfStatements&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The RDF statements for the Semantic Soulbound Token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CreateRDF&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;  rdfStatements&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when updating the RDF data of Semantic Soulbound Token. RDF data is a collection of RDF statements that are used to represent information about resources.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for the Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rdfStatements&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The RDF statements for the semantic soulbound token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateRDF&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;  rdfStatements&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when burning or revoking Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for the Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rdfStatements&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The RDF statements for the Semantic Soulbound Token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RemoveRDF&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;  rdfStatements&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the RDF statements of the Semantic Soulbound Token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for the Semantic Soulbound Token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rdfStatements&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The RDF statements for the Semantic Soulbound Token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; rdfOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; rdfStatements&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;ISemanticRDFSchema&lt;&#x2F;code&gt;, an extension of ERC-721 Metadata, is &lt;strong&gt;OPTIONAL&lt;&#x2F;strong&gt; for this standard, it is used to get the Schema URI for the RDF data.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ISemanticRDFSchema&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the URI of schema for this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; URI of the contract which point to a configuration profile.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; schemaURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;method-specification&quot;&gt;Method Specification&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;rdfOf (uint256 tokenId)&lt;&#x2F;code&gt;: Query the RDF data for the Semantic Soulbound Token by &lt;code&gt;tokenId&lt;&#x2F;code&gt;. The returned RDF data format conforms to the W3C RDF standard. RDF data is a collection of RDF statements that are used to represent information about resources. An RDF statement, also known as a triple, is a unit of information in the RDF data model. It consists of three parts: a subject, a predicate, and an object.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;schemaURI()&lt;&#x2F;code&gt;: This &lt;strong&gt;OPTIONAL&lt;&#x2F;strong&gt; method is used to query the URIs of the schema for the RDF data. RDF Schema is an extension of the basic RDF vocabulary and provides a data-modelling vocabulary for RDF data. It is &lt;strong&gt;RECOMMENDED&lt;&#x2F;strong&gt; to store the RDF Schema in decentralized storage such as Arweave or IPFS. The URIs are then stored in the contract and can be queried by this method.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;event-specification&quot;&gt;Event Specification&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;CreateRDF&lt;&#x2F;code&gt;: When minting a Semantic Soulbound Token, this event &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be triggered to notify the listener to perform operations with the created RDF data. When calling the event, the input RDF data &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be RDF statements, which are units of information consisting of three parts: a subject, a predicate, and an object.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;UpdateRDF&lt;&#x2F;code&gt;: When updating RDF data for a Semantic Soulbound Token, this event &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be triggered to notify the listener to perform update operations accordingly with the updated RDF data. When calling the event, the input RDF data &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be RDF statements, which are units of information consisting of three parts: a subject, a predicate, and an object.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;RemoveRDF&lt;&#x2F;code&gt;: When burning or revoking a Semantic Soulbound Token, this event &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be triggered to notify the listener to perform operations with the removed RDF data for the Semantic SBT. When calling the event, the input RDF data &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be RDF statements, which are units of information consisting of three parts: a subject, a predicate, and an object.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;RDF is a flexible and extensible data model based on creating subject-predicate-object relationships, often used to model graph data due to its semantic web standards, Linked Data concept, flexibility, and query capabilities. RDF allows graph data to be easily integrated with other data sources on the web, making it possible to create more comprehensive and interoperable models. The advantage of using RDF for semantic description is that it can describe richer information, including terms, categories, properties, and relationships. RDF uses standard formats and languages to describe metadata, making the expression of semantic information more standardized and unified. This helps to establish more accurate and reliable semantic networks, promoting interoperability between different systems. Additionally, RDF supports semantic reasoning, which allows the system to automatically infer additional relationships and connections between nodes in the social graph based on the existing data.&lt;&#x2F;p&gt;
&lt;p&gt;There are multiple formats for RDF statements. We list six most widely adopted RDF statement formats in the EIP: &lt;code&gt;Turtle&lt;&#x2F;code&gt;, &lt;code&gt;N-Triples&lt;&#x2F;code&gt;, &lt;code&gt;RDF&#x2F;XML&lt;&#x2F;code&gt;, &lt;code&gt;RDF&#x2F;JSON&lt;&#x2F;code&gt;,&lt;code&gt;N-Quads&lt;&#x2F;code&gt;, and &lt;code&gt;TriG&lt;&#x2F;code&gt;. These formats have different advantages and applicability in expressing, storing, and parsing RDF statements. Among these, &lt;code&gt;Turtle&lt;&#x2F;code&gt; is a popular format in RDF statements, due to its good human-readability and concision. It is typically used as the default format in this EIP for RDF statements. Using the Turtle format can make RDF statements easier to understand and maintain, while reducing the need for storage, suitable for representing complex RDF graphs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5192&#x2F;&quot;&gt;ERC-5192&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Composable NFTs utilizing Equippable Parts</title>
        <published>2022-12-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Cicada</name><uri>https://github.com/CicadaNCR</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6220/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6220-composable-nfts-utilizing-equippable-parts/12289" />
        

        <id>https://wg-eips.ritovision.com/6220/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:6220"
            label="ERC-6220" />
        

        
        

        
        <summary type="html">An interface for Composable non-fungible tokens through fixed and slot parts equipping.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6220/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Composable NFTs utilizing equippable parts standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; by allowing the NFTs to selectively add parts to themselves via equipping.&lt;&#x2F;p&gt;
&lt;p&gt;Tokens can be composed by cherry picking the list of parts from a Catalog for each NFT instance, and are able to equip other NFTs into slots, which are also defined within the Catalog. Catalogs contain parts from which NFTs can be composed.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal introduces two types of parts; slot type of parts and fixed type of parts. The slot type of parts allow for other NFT collections to be equipped into them, while fixed parts are full components with their own metadata.&lt;&#x2F;p&gt;
&lt;p&gt;Equipping a part into an NFT doesn&#x27;t generate a new token, but rather adds another component to be rendered when retrieving the token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability for tokens to equip other tokens and be composed from a set of available parts allows for greater utility, usability and forward compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;In the four years since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; was published, the need for additional functionality has resulted in countless extensions. This EIP improves upon ERC-721 in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;#composing&quot;&gt;Composing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;#token-progression&quot;&gt;Token progression&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;#merit-tracking&quot;&gt;Merit tracking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;#provable-digital-scarcity&quot;&gt;Provable Digital Scarcity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;composing&quot;&gt;Composing&lt;&#x2F;h3&gt;
&lt;p&gt;NFTs can work together to create a greater construct. Prior to this proposal, multiple NFTs could be composed into a single construct either by checking all of the compatible NFTs associated with a given account and used indiscriminately (which could result in unexpected result if there was more than one NFT intended to be used in the same slot), or by keeping a custom ledger of parts to compose together (either in a smart contract or an off-chain database). This proposal establishes a standardized framework for composable NFTs, where a single NFT can select which parts should be a part of the whole, with the information being on chain. Composing NFTs in such a way allows for virtually unbounded customization of the base NFT. An example of this could be a movie NFT. Some parts, like credits, should be fixed. Other parts, like scenes, should be interchangeable, so that various releases (base version, extended cuts, anniversary editions,...) can be replaced.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;token-progression&quot;&gt;Token progression&lt;&#x2F;h3&gt;
&lt;p&gt;As the token progresses through various stages of its existence, it can attain or be awarded various parts. This can be explained in terms of gaming. A character could be represented by an NFT utilizing this proposal and would be able to equip gear acquired through the gameplay activities and as it progresses further in the game, better items would be available. In stead of having numerous NFTs representing the items collected through its progression, equippable parts can be unlocked and the NFT owner would be able to decide which items to equip and which to keep in the inventory (not equipped) without need of a centralized party.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;merit-tracking&quot;&gt;Merit tracking&lt;&#x2F;h3&gt;
&lt;p&gt;An equippable NFT can also be used to track merit. An example of this is academic merit. The equippable NFT in this case would represent a sort of digital portfolio of academic achievements, where the owner would be able to equip their diplomas, published articles and awards for all to see.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;provable-digital-scarcity&quot;&gt;Provable Digital Scarcity&lt;&#x2F;h3&gt;
&lt;p&gt;The majority of current NFT projects are only mock-scarce. Even with a limited supply of tokens, the utility of these (if any) is uncapped. As an example, you can log into 500 different instances of the same game using the same wallet and the same NFT. You can then equip the same hat onto 500 different in-game avatars at the same time, because its visual representation is just a client-side mechanic.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal adds the ability to enforce that, if a hat is equipped on one avatar (by being sent into it and then equipped), it cannot be equipped on another. This provides real digital scarcity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;equippable-tokens&quot;&gt;Equippable tokens&lt;&#x2F;h3&gt;
&lt;p&gt;The interface of the core smart contract of the equippable tokens.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-6220 Composable NFTs utilizing Equippable Parts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6220&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x28bc9ae4.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC5773.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6220&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5773&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;*, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC165&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to store the core structure of the `Equippable` component.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the asset equipping a child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAssetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the asset used as equipment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of token that is equipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childEquippableAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection to which the child asset belongs to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Equipment&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; childAssetId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; childEquippableAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to provide a struct for inputing equip data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only used for input and not storage of data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token we are managing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of a child in the list of token&amp;#39;s active children&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that we are equipping into&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the slot part that we are using to equip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAssetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that we are equipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IntakeEquip&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; slotPartId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; childAssetId&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a child&amp;#39;s asset has been equipped into one of its parent assets.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that had an asset equipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset associated with the token we are equipping into&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the slot we are using to equip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token we are equipping into the slot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAssetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset associated with the token we are equipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildAssetEquipped&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAssetId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a child&amp;#39;s asset has been unequipped from one of its parent assets.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that had an asset unequipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset associated with the token we are unequipping out of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the slot we are unequipping from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being unequipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection that a token that is being unequipped belongs to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAssetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset associated with the token we are unequipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildAssetUnequipped&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAssetId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the assets belonging to a `equippableGroupId` have been marked as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  equippable into a given slot and parent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippableGroupId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the equippable group being marked as equippable into the slot associated with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `slotPartId` of the `parentAddress` collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the slot part of the catalog into which the parts belonging to the equippable group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  associated with `equippableGroupId` can be equipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection into which the parts belonging to `equippableGroupId` can be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  equipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ValidParentEquippableGroupIdSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; equippableGroupId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentAddress&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to equip a child into a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `IntakeEquip` struct contains the following data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      childIndex,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      assetId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      slotPartId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      childAssetId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An `IntakeEquip` struct specifying the equip data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; equip&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        IntakeEquip&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to unequip child from parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This can only be called by the owner of the token or by an account that has been granted permission to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  manage the given token by the current owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent from which the child is being unequipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent&amp;#39;s asset that contains the `Slot` into which the child is equipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the `Slot` from which to unequip the child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unequip&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotPartId&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to check whether the token has a given child equipped.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is used to prevent from transferring a child that is equipped.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which we are querying for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean value indicating whether the child token is equipped into the given token or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isChildEquipped&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to verify whether a token can be equipped into a given parent&amp;#39;s slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the parent token&amp;#39;s smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token we want to equip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset associated with the token we want to equip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the slot that we want to equip the token into&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean indicating whether the token with the given asset can be equipped into the desired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  slot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canTokenBeEquippedWithAssetIntoSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the Equipment object equipped into the specified slot of the desired token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `Equipment` struct consists of the following data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      assetId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      childAssetId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      childId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      childEquippableAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which we are retrieving the equipped object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; targetCatalogAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the `Catalog` associated with the `Slot` part of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; slotPartId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the `Slot` part that we are checking for equipped objects&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `Equipment` struct containing data about the equipped object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getEquipment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetCatalogAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotPartId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Equipment&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to get the asset and equippable data associated with given `assetId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which to retrieve the asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset of which we are retrieving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata URI of the asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippableGroupId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the equippable group this asset belongs to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; catalogAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the catalog the part belongs to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of parts included in the asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getAssetAndEquippableData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        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 class=&quot;z-support&quot;&gt;            string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataURI&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; equippableGroupId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; catalogAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partIds&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&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;h3 id=&quot;catalog&quot;&gt;Catalog&lt;&#x2F;h3&gt;
&lt;p&gt;The interface of the Catalog containing the equippable parts. Catalogs are collections of equippable fixed and slot parts and are not restricted to a single collection, but can support any number of NFT collections.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ICatalog&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An interface Catalog for equippable module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xd912401f.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ICatalog&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event to announce addition of a new part.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is emitted when a new part is added.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part that was added&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; itemType&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enum value specifying whether the part is `None`, `Slot` and `Fixed`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; zIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An uint specifying the z value of the part. It is used to specify the depth which the part should&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  be rendered at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippableAddresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of addresses that can equip this part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata URI of the part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddedPart&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;        ItemType&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; itemType&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; zIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; equippableAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataURI&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event to announce new equippables to the part.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is emitted when new addresses are marked as equippable for `partId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part that had new equippable addresses added&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippableAddresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of the new addresses that can equip this part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddedEquippables&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; equippableAddresses&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event to announce the overriding of equippable addresses of the part.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is emitted when the existing list of addresses marked as equippable for `partId` is overwritten by a new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  one.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part whose list of equippable addresses was overwritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippableAddresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new, full, list of addresses that can equip this part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SetEquippables&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; equippableAddresses&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event to announce that a given part can be equipped by any address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is emitted when a given part is marked as equippable by any.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part marked as equippable by any address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SetEquippableToAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to define a type of the item. Possible values are `None`, `Slot` or `Fixed`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used for fixed and slot parts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ItemType&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Fixed&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The integral structure of a standard RMRK catalog item defining it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requires a minimum of 3 storage slots per catalog item, equivalent to roughly 60,000 gas as of Berlin hard fork&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  (April 14, 2021), though 5-7 storage slots is more realistic, given the standard length of an IPFS URI. This&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  will result in between 25,000,000 and 35,000,000 gas per 250 assets--the maximum block size of Ethereum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  mainnet is 30M at peak usage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; itemType&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The item type of the part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The z value of the part defining how it should be rendered when presenting the full NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; equippable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The array of addresses allowed to be equipped in this part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata URI of the part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Part&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ItemType itemType&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint8&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; equippable&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;n Collections that can be equipped into this slot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; metadataURI&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;n bytes 32+&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The structure used to add a new `Part`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The part is added with specified ID, so you have to make sure that you are using an unused `partId`,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  otherwise the addition of the part vill be reverted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The full `IntakeStruct` looks like this:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *          partID,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *          itemType,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *          z,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *          [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *               permittedCollectionAddress0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *               permittedCollectionAddress1,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *               permittedCollectionAddress2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *           ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *           metadataURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *       ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *   ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID to be assigned to the `Part`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; part&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A `Part` to be added&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IntakeStruct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Part part&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to return the metadata URI of the associated catalog.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Base metadata URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getMetadataURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to return the `itemType` of the associated catalog&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `itemType` of the associated catalog&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getType&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to check whether the given address is allowed to equip the desired `Part`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if a collection may equip asset with `partId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the part that we are checking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; targetAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that we are checking for whether the part can be equipped into it or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The status indicating whether the `targetAddress` can be equipped into `Part` with `partId` or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkIsEquippable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; targetAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to check if the part is equippable by all addresses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if part is equippable to all.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part that we are checking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The status indicating whether the part with `partId` can be equipped by any address or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkIsEquippableToAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve a `Part` with id `partId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the part that we are retrieving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `Part` struct associated with given `partId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getPart&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Part&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve multiple parts at the same time.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; partIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of part IDs that we want to retrieve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of `Part` structs associated with given `partIds`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getParts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; partIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Part&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Why are we using a Catalog in stead of supporting direct NFT equipping?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
If NFTs could be directly equipped into other NFTs without any oversight, the resulting composite would be unpredictable. Catalog allows for parts to be pre-verified in order to result in a composite that composes as expected. Another benefit of Catalog is the ability of defining reusable fixed parts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why do we propose two types of parts?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Some parts, that are the same for all of the tokens, don&#x27;t make sense to be represented by individual NFTs, so they can be represented by fixed parts. This reduces the clutter of the owner&#x27;s wallet as well as introduces an efficient way of disseminating repetitive assets tied to NFTs.&lt;br &#x2F;&gt;
The slot parts allow for equipping NFTs into them. This provides the ability to equip unrelated NFT collections into the base NFT after the unrelated collection has been verified to compose properly.&lt;br &#x2F;&gt;
Having two parts allows for support of numerous use cases and, since the proposal doesn&#x27;t enforce the use of both it can be applied in any configuration needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is a method to get all of the equipped parts not included?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Getting all parts might not be an operation necessary for all implementers. Additionally, it can be added either as an extension, doable with hooks, or can be emulated using an indexer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should Catalog be limited to support one NFT collection at a time or be able to support any nunmber of collections?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
As the Catalog is designed in a way that is agnostic to the use case using it. It makes sense to support as wide reusability as possible. Having one Catalog supporting multiple collections allows for optimized operation and reduced gas prices when deploying it and setting fixed as well as slot parts.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;fixed-parts&quot;&gt;Fixed parts&lt;&#x2F;h3&gt;
&lt;p&gt;Fixed parts are defined and contained in the Catalog. They have their own metadata and are not meant to change through the lifecycle of the NFT.&lt;&#x2F;p&gt;
&lt;p&gt;A fixed part cannot be replaced.&lt;&#x2F;p&gt;
&lt;p&gt;The benefit of fixed parts is that they represent equippable parts that can be equipped by any number of tokens in any number of collections and only need to be defined once.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;slot-parts&quot;&gt;Slot parts&lt;&#x2F;h3&gt;
&lt;p&gt;Slot parts are defined and contained in the Catalog. They don&#x27;t have their own metadata, but rather support equipping of selected NFT collections into them. The tokens equipped into the slots however, contain their own metadata. This allows for an equippable modifialbe content of the base NFT controlled by its owner. As they can be equipped into any number of tokens of any number of collections, they allow for reliable composing of the final tokens by vetting which NFTs can be equipped by a given slot once and then reused any number of times.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Equippable token standard has been made compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; in order to take advantage of the robust tooling available for implementations of ERC-721 and to ensure compatibility with existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;.&#x2F;assets&#x2F;test&#x2F;equippableFixedParts.ts&quot;&gt;&lt;code&gt;equippableFixedParts.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;.&#x2F;assets&#x2F;test&#x2F;equippableSlotParts.ts&quot;&gt;&lt;code&gt;equippableSlotParts.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-6220&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6220&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;EquippableToken.sol&quot;&gt;&lt;code&gt;EquippableToken.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; apply: hidden logic may be present in any of the functions, including burn, add resource, accept resource, and more.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hierarchical NFTs</title>
        <published>2022-12-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Keegan Lee</name><uri>https://github.com/keeganlee</uri>
	</author>
	
	<author>
		<name>msfew</name><email>msfew@hyperoracle.io</email>
	</author>
	
	<author>
		<name>Kartin</name><email>kartin@hyperoracle.io</email>
	</author>
	
	<author>
		<name>qizhou</name><uri>https://github.com/qizhou</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6150/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6150-hierarchical-nfts-an-extension-to-erc-721/12173" />
        

        <id>https://wg-eips.ritovision.com/6150/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:6150"
            label="ERC-6150" />
        

        
        

        
        <summary type="html">Hierarchical NFTs, an extension to EIP-721.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6150/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;. It proposes a multi-layer filesystem-like hierarchical NFTs. This standard provides interfaces to get parent NFT or children NFTs and whether NFT is a leaf node or root node, maintaining the hierarchical relationship among them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes the interface of filesystem-like hierarchical NFTs and provides a reference implementation.&lt;&#x2F;p&gt;
&lt;p&gt;Hierarchy structure is commonly implemented for file systems by operating systems such as Linux Filesystem Hierarchy (FHS).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6150&#x2F;.&#x2F;assets&#x2F;linux-hierarchy.png&quot; alt=&quot;Linux Hierarchical File Structure&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Websites often use a directory and category hierarchy structure, such as eBay (Home -&amp;gt; Electronics -&amp;gt; Video Games -&amp;gt; Xbox -&amp;gt; Products), and Twitter (Home -&amp;gt; Lists -&amp;gt; List -&amp;gt; Tweets), and Reddit (Home -&amp;gt; r&#x2F;ethereum -&amp;gt; Posts -&amp;gt; Hot).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6150&#x2F;.&#x2F;assets&#x2F;website-hierarchy.png&quot; alt=&quot;Website Hierarchical Structure&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A single smart contract can be the &lt;code&gt;root&lt;&#x2F;code&gt;, managing every directory&#x2F;category as individual NFT and hierarchy relations of NFTs. Each NFT&#x27;s &lt;code&gt;tokenURI&lt;&#x2F;code&gt; may be another contract address, a website link, or any form of metadata.&lt;&#x2F;p&gt;
&lt;p&gt;The advantages and the advancement of the Ethereum ecosystem of using this standard include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Complete on-chain storage of hierarchy, which can also be governed on-chain by additional DAO contract&lt;&#x2F;li&gt;
&lt;li&gt;Only need a single contract to manage and operate the hierarchical relations&lt;&#x2F;li&gt;
&lt;li&gt;Transferrable directory&#x2F;category ownership as NFT, which is great for use cases such as on-chain forums&lt;&#x2F;li&gt;
&lt;li&gt;Easy and permissionless data access to the hierarchical structure by front-end&lt;&#x2F;li&gt;
&lt;li&gt;Ideal structure for traditional applications such as e-commerce, or forums&lt;&#x2F;li&gt;
&lt;li&gt;Easy-to-understand interfaces for developers, which are similar to Linux filesystem commands in concept&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The use cases can include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On-chain forum, like Reddit&lt;&#x2F;li&gt;
&lt;li&gt;On-chain social media, like Twitter&lt;&#x2F;li&gt;
&lt;li&gt;On-chain corporation, for managing organizational structures&lt;&#x2F;li&gt;
&lt;li&gt;On-chain e-commerce platforms, like eBay or individual stores&lt;&#x2F;li&gt;
&lt;li&gt;Any application with tree-like structures&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the future, with the development of the data availability solutions of Ethereum and an external permissionless data retention network, the content (posts, listed items, or tweets) of these platforms can also be entirely stored on-chain, thus realizing fully decentralized applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Every compliant contract must implement this proposal, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt; interfaces.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x897e2c73.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC721, IERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `tokenId` token under `parentId` is minted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; minter&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of minter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address received token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of parent token, if it&amp;#39;s zero, it means minted `tokenId` is a root token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of minted token, required to be greater than zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Minted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; minter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the parent token of `tokenId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Parent token found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; parentOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the children tokens of `tokenId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childrenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The array of children tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childrenOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childrenIds&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check the `tokenId` token if it is a root token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token want to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if it is a root token; if not, return `false`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isRoot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check the `tokenId` token if it is a leaf token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token want to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if it is a leaf token; if not, return `false`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isLeaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optional Extension: Enumerable&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xba541a2e.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150Enumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC721Enumerable&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get total amount of children tokens under `parentId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If `parentId` is zero, it means get total amount of root tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; total amount of children tokens under `parentId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childrenCountOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the token at the specified index of all children tokens under `parentId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If `parentId` is zero, it means get root token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token ID at `index` of all chlidren tokens under `parentId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childOfParentByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the index position of specified token in the children enumeration under specified parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if the `tokenId` is not found in the children enumeration.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If `parentId` is zero, means get root token index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified token to be found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; index position of `tokenId` found in the children enumeration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; indexInChildrenEnumeration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optional Extension: Burnable&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x4ac0aa46.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150Burnable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Burn the `tokenId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `tokenId` is not a leaf token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws if `tokenId` is not a valid NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws if `owner` is not the owner of `tokenId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to be burnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Batch burn tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if one of `tokenIds` is not a leaf token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws if one of `tokenIds` is not a valid NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws if `owner` is not the owner of all `tokenIds` tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for all `tokenIds`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The tokens to be burnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeBatchBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optional Extension: ParentTransferable&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xfa574808.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150ParentTransferable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the parent of `tokenId` token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; oldParentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Previous parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newParentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ParentTransferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldParentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newParentId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer parentship of `tokenId` token to a new parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newParentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New parent token id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to be &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferParent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newParentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Batch transfer parentship of `tokenIds` to a new parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newParentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New parent token id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Array of token ids to be &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchTransferParent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newParentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optional Extension: Access Control&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x1d04f0b3.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150AccessControl&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6150&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check the account whether a admin of `tokenId` token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Each token can be set more than one admin. Admin have permission to do something to the token, like mint child token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * or burn token, or transfer parentship.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; If&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account has admin permission, return true; otherwise, return false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isAdminOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check whether the specified parent token and account can mint children tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the `parentId` is zero, check whether account can mint root nodes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified parent token to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified account to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; If&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the token and account has mint permission, return true; otherwise, return false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canMintChildren&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check whether the specified token can be burnt by specified account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified token to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The specified account to be checked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; If&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the tokenId can be burnt by account, return true; otherwise, return false.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canBurnTokenByAccount&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the abstract, this EIP&#x27;s goal is to have a simple interface for supporting Hierarchical NFTs. Here are a few design decisions and why they were made:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;relationship-between-nfts&quot;&gt;Relationship between NFTs&lt;&#x2F;h3&gt;
&lt;p&gt;All NFTs will make up a hierarchical relationship tree. Each NFT is a node of the tree, maybe as a root node or a leaf node, as a parent node or a child node.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal standardizes the event &lt;code&gt;Minted&lt;&#x2F;code&gt; to indicate the parent and child relationship when minting a new node. When a root node is minted, parentId should be zero. That means a token id of zero could not be a real node. So a real node token id must be greater than zero.&lt;&#x2F;p&gt;
&lt;p&gt;In a hierarchical tree, it&#x27;s common to query upper and lower nodes. So this proposal standardizes function &lt;code&gt;parentOf&lt;&#x2F;code&gt; to get the parent node of the specified node and standardizes function &lt;code&gt;childrenOf&lt;&#x2F;code&gt; to get all children nodes.&lt;&#x2F;p&gt;
&lt;p&gt;Functions &lt;code&gt;isRoot&lt;&#x2F;code&gt; and &lt;code&gt;isLeaf&lt;&#x2F;code&gt; can check if one node is a root node or a leaf node, which would be very useful for many cases.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enumerable-extension&quot;&gt;Enumerable Extension&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal standardizes three functions as an extension to support enumerable queries involving children nodes. Each function all have param &lt;code&gt;parentId&lt;&#x2F;code&gt;, for compatibility, when the &lt;code&gt;parentId&lt;&#x2F;code&gt; specified zero means query root nodes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parenttransferable-extension&quot;&gt;ParentTransferable Extension&lt;&#x2F;h3&gt;
&lt;p&gt;In some cases, such as filesystem, a directory or a file could be moved from one directory to another. So this proposal adds ParentTransferable Extension to support this situation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;access-control&quot;&gt;Access Control&lt;&#x2F;h3&gt;
&lt;p&gt;In a hierarchical structure, usually, there is more than one account has permission to operate a node, like mint children nodes, transfer node, burn node. This proposal adds a few functions as standard to check access control permissions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Implementation: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6150&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC6150.sol&quot;&gt;EIP-6150&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security considerations were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Forkid checks based on timestamps</title>
        <published>2022-12-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6122/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6122-forkid-checks-based-on-timestamps/12130" />
        

        <id>https://wg-eips.ritovision.com/6122/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        

        
        <category
            term="tag:eip:6122"
            label="EIP-6122" />
        

        
        

        
        <summary type="html">Modifies the forkid checks to work with timestamps and block numbers</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6122/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt; proposed a way of identifying nodes on the p2p network based on their chain configuration via the forkid parameter.
It allows nodes to cut incompatible nodes off quickly which makes the P2P network more reliable.
After the merge, forks are scheduled by block time instead of block number. This EIP updates the forkid calculation with block time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;While in proof-of-work forks were scheduled by block number, the proof-of-stake consensus layer schedules forks by slot number. The slot number is a time based measurement. In order to schedule forks at the same time on the consensus and execution layer, the execution layer is forced to also schedule forks by timestamp after the merge.&lt;&#x2F;p&gt;
&lt;p&gt;The forkid calculation allows peers to quickly determine the configuration of peers and disconnect peers that are misconfigured or configured for other networks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Each node maintains the following values:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_HASH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: IEEE CRC32 checksum (&lt;code&gt;[4]byte&lt;&#x2F;code&gt;) of the genesis hash and fork blocks numbers or timestamps that already passed.
&lt;ul&gt;
&lt;li&gt;The fork block numbers or timestamps are fed into the CRC32 checksum in ascending order.&lt;&#x2F;li&gt;
&lt;li&gt;If multiple forks are applied at the same block or time, the block number or timestamp is checksummed only once.&lt;&#x2F;li&gt;
&lt;li&gt;Block numbers are regarded as &lt;code&gt;uint64&lt;&#x2F;code&gt; integers, encoded in big endian format when checksumming.&lt;&#x2F;li&gt;
&lt;li&gt;Block timestamps are regarded as &lt;code&gt;uint64&lt;&#x2F;code&gt; integers, encoded in big endian format when checksumming.&lt;&#x2F;li&gt;
&lt;li&gt;If a chain is configured to start with a non-Frontier ruleset already in its genesis, that is NOT considered a fork.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Block number or timestamp (&lt;code&gt;uint64&lt;&#x2F;code&gt;) of the next upcoming fork, or &lt;code&gt;0&lt;&#x2F;code&gt; if no next fork is known.
&lt;ul&gt;
&lt;li&gt;Note that it is not important to distinguish between a timestamp or a block for &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; for a timestamp based fork at &lt;code&gt;1668000000&lt;&#x2F;code&gt; on top of homestead would be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;forkhash₁ = &lt;code&gt;0xcb37b2ee&lt;&#x2F;code&gt; (homestead+fictional fork) = &lt;code&gt;CRC32(&amp;lt;genesis-hash&amp;gt; || uint64(1150000) || uint64(1668000000))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;additional-rules&quot;&gt;Additional rules&lt;&#x2F;h3&gt;
&lt;p&gt;The following additional rules are applied:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Forks by timestamp MUST be scheduled at or after the forks by block (on mainnet as well as on private networks).&lt;&#x2F;li&gt;
&lt;li&gt;An implementation of forkid verification of remote peer needs to filter the incoming forkids first by block then by timestamp.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Shanghai will be scheduled by timestamp thus the forkid calculations need to be updated to work with timestamps and blocks.
Since all block number based forks are before time based forks, nodes need to check the block based forks before the time based forks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This change modifies the forkid calculation slightly.
As a consequence nodes applying this change will drop peers who are not applying this change as soon as timestamp-scheduled fork occurs.
This is not only expected, but actually the purpose of the forkid in the first place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s a suite of tests with mainnet config and withdrawals enabled at time &lt;code&gt;1668000000&lt;&#x2F;code&gt; and merge netsplit block at block &lt;code&gt;18000000&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; testcase&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	head&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	want&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&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 class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	config&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ChainConfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	genesis&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; common&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	cases&lt;&#x2F;span&gt;&lt;span&gt;   [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&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&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Withdrawal test cases&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;withdrawalConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MainnetGenesisHash&lt;&#x2F;span&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;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&lt;&#x2F;span&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;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;fc64ec04&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1150000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;           &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unsynced&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 class=&quot;z-constant&quot;&gt;1149999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;fc64ec04&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1150000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Frontier block&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 class=&quot;z-constant&quot;&gt;1150000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97c2c34c&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1920000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Homestead block&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 class=&quot;z-constant&quot;&gt;1919999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97c2c34c&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1920000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Homestead block&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 class=&quot;z-constant&quot;&gt;1920000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;91d1f948&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2463000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First DAO block&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 class=&quot;z-constant&quot;&gt;2462999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;91d1f948&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2463000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last DAO block&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 class=&quot;z-constant&quot;&gt;2463000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7a64da13&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2675000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Tangerine block&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 class=&quot;z-constant&quot;&gt;2674999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7a64da13&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2675000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Tangerine block&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 class=&quot;z-constant&quot;&gt;2675000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Spurious block&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 class=&quot;z-constant&quot;&gt;4369999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Spurious block&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 class=&quot;z-constant&quot;&gt;4370000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Byzantium block&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Byzantium block&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 class=&quot;z-constant&quot;&gt;7280000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9069000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First and last Constantinople, first Petersburg block&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 class=&quot;z-constant&quot;&gt;9068999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9069000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Petersburg block&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 class=&quot;z-constant&quot;&gt;9069000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;879d6e30&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9200000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Istanbul and first Muir Glacier block&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 class=&quot;z-constant&quot;&gt;9199999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;879d6e30&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9200000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Istanbul and first Muir Glacier block&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 class=&quot;z-constant&quot;&gt;9200000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;e029e991&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12244000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Muir Glacier block&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 class=&quot;z-constant&quot;&gt;12243999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;e029e991&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12244000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Muir Glacier block&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 class=&quot;z-constant&quot;&gt;12244000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0eb440f6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12965000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Berlin block&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 class=&quot;z-constant&quot;&gt;12964999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0eb440f6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12965000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Berlin block&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 class=&quot;z-constant&quot;&gt;12965000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;b715077d&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13773000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First London block&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 class=&quot;z-constant&quot;&gt;13772999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;b715077d&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13773000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last London block&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 class=&quot;z-constant&quot;&gt;13773000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20c327fc&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15050000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Arrow Glacier block&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 class=&quot;z-constant&quot;&gt;15049999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20c327fc&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15050000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Arrow Glacier block&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 class=&quot;z-constant&quot;&gt;15050000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;f0afd0e3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18000000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Gray Glacier block&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 class=&quot;z-constant&quot;&gt;18000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4fb8a872&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Merge Start block&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4fb8a872&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Merge Start block&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c1fdf181&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Shanghai block&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 class=&quot;z-constant&quot;&gt;20100000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2669000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c1fdf181&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Future Shanghai block&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&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;Here&#x27;s a suite of tests of the different states a Mainnet node might be in and the different remote fork identifiers it might be required to validate and decide to accept or reject:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	head&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	id&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;   ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	err&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  error&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&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F; Local is mainnet Withdrawals, remote announces the same. No future fork is announced.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c1fdf181&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, remote announces the same also announces a next fork&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; at block&#x2F;time 0xffffffff, but that is uncertain.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c1fdf181&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint64&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg &amp;amp; Withdrawals), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, but it&amp;#39;s not yet aware of Petersburg (e.g. non updated node before the fork).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; In this case we don&amp;#39;t know if Petersburg passed yet or not.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1667999999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg &amp;amp; Withdrawals), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, and it&amp;#39;s also aware of Petersburg (e.g. updated node before the fork). We&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; don&amp;#39;t know if Petersburg passed yet (will pass) or not.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1667999999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg &amp;amp; Withdrawals), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, and it&amp;#39;s also aware of some random fork (e.g. misconfigured Petersburg). As&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; neither forks passed at neither nodes, they may mismatch, but we still connect for now.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1667999999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint64&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet exactly on Withdrawals, remote announces Byzantium + knowledge about Petersburg. Remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is simply out of sync, accept.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, remote announces Byzantium + knowledge about Petersburg. Remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is simply out of sync, accept.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, remote announces Spurious + knowledge about Byzantium. Remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is definitely out of sync. It may or may not need the Petersburg update, we don&amp;#39;t know yet.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Byzantium &amp;amp; pre-withdrawals, remote announces Petersburg. Local is out of sync, accept.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1667999999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; out of sync. Local also knows about a future fork, but that is uncertain yet.&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 class=&quot;z-constant&quot;&gt;4369999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1667999999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals. remote announces Byzantium but is not aware of further forks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remote needs software update.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrRemoteStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, and isn&amp;#39;t aware of more forks. Remote announces Petersburg +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 0xffffffff. Local needs software update, reject.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5cddc0e1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, and is aware of Petersburg. Remote announces Petersburg +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 0xffffffff. Local needs software update, reject.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5cddc0e1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, remote is Rinkeby Petersburg.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;afec6b27&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals, far in the future. Remote announces Gopherium (non existing fork)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; at some future block 88888888, for itself, but past block for local. Local is incompatible.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).&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 class=&quot;z-constant&quot;&gt;88888888&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;f0afd0e3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 88888888&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrRemoteStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Withdrawals. Remote is in Byzantium, but announces Gopherium (non existing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; fork) at block 7279999, before Petersburg. Local is incompatible.&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 class=&quot;z-constant&quot;&gt;20000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1668000001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksumToBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7279999&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrRemoteStale&lt;&#x2F;span&gt;&lt;span&gt;}&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;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No known security risks&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Supply validator deposits on chain</title>
        <published>2022-12-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mikhail Kalinin</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Peter Davies</name><uri>https://github.com/petertdavies</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6110/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6110-supply-validator-deposits-on-chain/12072" />
        

        <id>https://wg-eips.ritovision.com/6110/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6110"
            label="EIP-6110" />
        

        
        

        
        <summary type="html">Provides validator deposits as a list of deposit operations added to the Execution Layer block</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6110/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Appends validator deposits to the Execution Layer block structure. This shifts responsibility of deposit inclusion and validation to the Execution Layer and removes the need for deposit (or &lt;code&gt;eth1data&lt;&#x2F;code&gt;) voting from the Consensus Layer.&lt;&#x2F;p&gt;
&lt;p&gt;Validator deposits list supplied in a block is obtained by parsing deposit contract log events emitted by each deposit transaction included in a given block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Validator deposits are a core component of the proof-of-stake consensus mechanism. This EIP allows for an in-protocol mechanism of deposit processing on the Consensus Layer and eliminates the proposer voting mechanism utilized currently. This proposed mechanism relaxes safety assumptions and reduces complexity of client software design, contributing to the security of the deposits flow. It also improves validator UX.&lt;&#x2F;p&gt;
&lt;p&gt;Advantages of in-protocol deposit processing consist of, but are not limited to, the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Significant increase of deposits security by supplanting proposer voting. With the proposed in-protocol mechanism, an honest online node can&#x27;t be convinced to process fake deposits even when more than 2&#x2F;3 portion of stake is adversarial.&lt;&#x2F;li&gt;
&lt;li&gt;Decrease of delay between submitting deposit transaction on Execution Layer and its processing on Consensus Layer. That is, ~13 minutes with in-protocol deposit processing compared to ~12 hours with the existing mechanism.&lt;&#x2F;li&gt;
&lt;li&gt;Eliminate beacon block proposal dependency on JSON-RPC API data polling that suffers from failures caused by inconsistencies between JSON-RPC API implementations and dependency of API calls processing on the inner state (e.g. syncing) of client software.&lt;&#x2F;li&gt;
&lt;li&gt;Eliminate requirement to maintain and distribute deposit contract snapshots (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;&quot;&gt;EIP-4881&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Reduction of design and engineering complexity of Consensus Layer client software on a component that has proven to be brittle.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;execution-layer&quot;&gt;Execution Layer&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&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_REQUEST_TYPE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;b&#x27;0&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; request type byte for deposit operation&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;configuration&quot;&gt;Configuration&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&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_CONTRACT_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00000000219ab540356cbb839cbe05303d7705fa&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Mainnet&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;DEPOSIT_EVENT_SIGNATURE_HASH&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;code&gt;, &lt;code&gt;DEPOSIT_EVENT_SIGNATURE_HASH&lt;&#x2F;code&gt; parameters &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be included into client software binary distribution.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; -- the first block in a blockchain after this EIP has been activated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;deposit-request&quot;&gt;Deposit request&lt;&#x2F;h4&gt;
&lt;p&gt;The structure denoting the new deposit request consists of the following fields:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;pubkey: Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;withdrawal_credentials: Bytes32&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;amount: uint64&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;signature: Bytes96&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;index: uint64&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Deposits are a type of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7685&#x2F;&quot;&gt;EIP-7685&lt;&#x2F;a&gt; request, with the following encoding:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_REQUEST_TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_deposit_request_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;receipts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;block-validity&quot;&gt;Block validity&lt;&#x2F;h4&gt;
&lt;p&gt;Beginning with the &lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;, each deposit accumulated in the block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; appear in the EIP-7685 requests list
in the order they appear in the logs. To illustrate:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; parse_deposit_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  Parses deposit data from DepositContract.DepositEvent data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  pass&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_valid_deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Verifies the layout of the DepositEvent. Returns `False` if the layout is unsupported,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    `True` if the layout is of the expected format.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 576&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&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;    pubkey_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    withdrawal_credentials_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    amount_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;96&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    signature_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;96&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;128&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    index_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;128&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;160&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pubkey_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 160&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        or&lt;&#x2F;span&gt;&lt;span&gt; withdrawal_credentials_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        or&lt;&#x2F;span&gt;&lt;span&gt; amount_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 320&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        or&lt;&#x2F;span&gt;&lt;span&gt; signature_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 384&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        or&lt;&#x2F;span&gt;&lt;span&gt; index_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 512&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&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; These sizes are the sizes of the relevant data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pubkey_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;pubkey_offset&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;pubkey_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    withdrawal_credentials_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;withdrawal_credentials_offset&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;withdrawal_credentials_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    amount_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;amount_offset&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;amount_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    signature_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;signature_offset&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;signature_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    index_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index_offset&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;index_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pubkey_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        and&lt;&#x2F;span&gt;&lt;span&gt; withdrawal_credentials_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        and&lt;&#x2F;span&gt;&lt;span&gt; amount_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        and&lt;&#x2F;span&gt;&lt;span&gt; signature_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        and&lt;&#x2F;span&gt;&lt;span&gt; index_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; event_data_to_deposit_request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parse_deposit_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_event_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&gt;    pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Bytes48&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;    withdrawal_credentials&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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&gt;    amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; deposit_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 8 bytes uint64 LE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Bytes96&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&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&gt;    index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; deposit_data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 8 bytes uint64 LE&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; pubkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; withdrawal_credentials&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; index&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_deposit_request_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;receipts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieve all deposits made in the block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_requests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; receipts&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; log&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; receipt&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;logs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_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 class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;topics&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;topics&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_EVENT_SIGNATURE_HASH&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                    assert&lt;&#x2F;span&gt;&lt;span&gt; is_valid_deposit_event_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid deposit log: unsupported data layout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    deposit_request&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; event_data_to_deposit_request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;                    deposit_requests&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_request&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Concatenate list of deposit request data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;join&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposit_requests&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;consensus-layer&quot;&gt;Consensus layer&lt;&#x2F;h3&gt;
&lt;p&gt;Consensus layer changes can be summarized into the following list:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ExecutionRequests&lt;&#x2F;code&gt; is extended with a new &lt;code&gt;deposit_requests&lt;&#x2F;code&gt; field to accommodate deposit requests list.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;BeaconState&lt;&#x2F;code&gt; is appended with &lt;code&gt;deposit_requests_start_index&lt;&#x2F;code&gt; used to switch from the former deposit mechanism to the new one.&lt;&#x2F;li&gt;
&lt;li&gt;As a part of transition logic a new beacon block validity condition is added to constrain the usage of &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll.&lt;&#x2F;li&gt;
&lt;li&gt;A new &lt;code&gt;process_deposit_request&lt;&#x2F;code&gt; function is added to the block processing routine to handle &lt;code&gt;deposit_requests&lt;&#x2F;code&gt; processing.&lt;&#x2F;li&gt;
&lt;li&gt;Validator guide provides a logic switching off &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll once transition is completed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Detailed consensus layer specification can be found in following documents:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;eba62dbf00132dfdc97fbfab663a99cb23b9e8f1&#x2F;specs&#x2F;electra&#x2F;beacon-chain.md&quot;&gt;&lt;code&gt;electra&#x2F;beacon-chain.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; -- state transition.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;eba62dbf00132dfdc97fbfab663a99cb23b9e8f1&#x2F;specs&#x2F;electra&#x2F;validator.md&quot;&gt;&lt;code&gt;electra&#x2F;validator.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; -- validator guide.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;eba62dbf00132dfdc97fbfab663a99cb23b9e8f1&#x2F;specs&#x2F;electra&#x2F;fork.md&quot;&gt;&lt;code&gt;electra&#x2F;fork.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; -- EIP activation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;validator-index-invariant&quot;&gt;Validator index invariant&lt;&#x2F;h4&gt;
&lt;p&gt;Due to the large follow distance of &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll an index of a new validator assigned during deposit processing remains the same across different branches of a block tree, i.e. with existing mechanism &lt;code&gt;(pubkey, index)&lt;&#x2F;code&gt; cache utilized by consensus layer clients is re-org resilient. The new deposit machinery breaks this invariant and consensus layer clients will have to deal with a fact that a validator index becomes fork dependent, i.e. a validator with the same &lt;code&gt;pubkey&lt;&#x2F;code&gt; can have different indexes in different block tree branches.&lt;&#x2F;p&gt;
&lt;p&gt;Detailed &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6110&#x2F;assets&#x2F;pubkey_to_index_cache_analysis&#x2F;&quot;&gt;analysis&lt;&#x2F;a&gt; shows that &lt;code&gt;process_deposit&lt;&#x2F;code&gt; function is &lt;em&gt;the only&lt;&#x2F;em&gt; place requiring a fork dependent &lt;code&gt;(pubkey, index)&lt;&#x2F;code&gt; cache.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;eth1data-poll-deprecation&quot;&gt;&lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll deprecation&lt;&#x2F;h4&gt;
&lt;p&gt;Consensus layer clients will be able to remove &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll mechanism in an uncoordinated fashion once transition period is finished. The transition period is considered as finished when a network reaches the point where &lt;code&gt;state.eth1_deposit_index == state.deposit_requests_start_index&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;index-field&quot;&gt;&lt;code&gt;index&lt;&#x2F;code&gt; field&lt;&#x2F;h3&gt;
&lt;p&gt;Deposit &lt;code&gt;index&lt;&#x2F;code&gt; is used to deterministically initialize &lt;code&gt;deposit_requests_start_index&lt;&#x2F;code&gt; in the &lt;code&gt;BeaconState&lt;&#x2F;code&gt;, this prevents same deposit from being applied twice during &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; poll deprecation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-limiting-the-size-of-deposit-operations-list&quot;&gt;Not limiting the size of deposit operations list&lt;&#x2F;h3&gt;
&lt;p&gt;The list is unbounded because of negligible data complexity and absence of potential DoS vectors. See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6110&#x2F;#security-considerations&quot;&gt;Security Considerations&lt;&#x2F;a&gt; for more details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;filtering-events-by-deposit-contract-address-and-deposit-event-signature-hash&quot;&gt;Filtering events by &lt;code&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;code&gt; and &lt;code&gt;DEPOSIT_EVENT_SIGNATURE_HASH&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Depending on the design, Deposit smart contract can emit different type of events when deposit is being processed. For instance, Deposit smart contract on Sepolia emits &lt;code&gt;Transfer&lt;&#x2F;code&gt; in addition to &lt;code&gt;DepositEvent&lt;&#x2F;code&gt;. Thus it is important to filter out irrelevant events.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backwards incompatible changes to the block structure and block validation rule set. But neither of these changes break anything related to user activity and experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;data-complexity&quot;&gt;Data complexity&lt;&#x2F;h3&gt;
&lt;p&gt;At the time of the latest update of this document, the total number of submitted deposits is 1,899,120 which is 348MB of deposit data. Assuming frequency of deposit transactions remains the same, historic chain data complexity induced by this EIP can be estimated as 84MB per year which is negligible in comparison to other historical data.&lt;&#x2F;p&gt;
&lt;p&gt;After the beacon chain launch in December 2020, the biggest observed spike in a number of submitted deposits was on June 1, 2023. More than 12,000 deposit transactions were submitted during 24 hours which on average is less than 2 deposit, or 384 bytes of data, per block.&lt;&#x2F;p&gt;
&lt;p&gt;Considering the above, we conclude that data complexity introduced by this proposal is negligible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dos-vectors&quot;&gt;DoS vectors&lt;&#x2F;h3&gt;
&lt;p&gt;The code in the deposit contract costs 15,650 gas to run in the cheapest case (when all storage slots are hot and only a single leaf has to be modified). Some deposits in a batch deposit are more expensive, but those costs, when amortized over a large number of deposits, are small at around ~1,000 gas per deposit. Under current gas pricing rules an extra 6,900 gas is charged to make a &lt;code&gt;CALL&lt;&#x2F;code&gt; that transfers ETH, this is a case of inefficient gas pricing and may be reduced in the future. For future robustness the beacon chain needs to be able to withstand 1,916 deposits in a 30M gas block (15,650 gas per deposit). The limit under current rules is less than 1,271 deposits in a 30M gas block.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;execution-layer-1&quot;&gt;Execution layer&lt;&#x2F;h4&gt;
&lt;p&gt;With 1 ETH as a minimum deposit amount, the lowest cost of a byte of deposit data is 1 ETH&#x2F;192 ~ 5,208,333 Gwei. This is several orders of magnitude higher than the cost of a byte of transaction&#x27;s calldata, thus adding deposit operations to a block does not increase DoS attack surface of the execution layer.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;consensus-layer-1&quot;&gt;Consensus layer&lt;&#x2F;h4&gt;
&lt;p&gt;The most consuming computation of deposit processing is signature verification. Its complexity is bounded by a maximum number of deposits per block which is around 1,271 with 30M gas block at the moment. So, it is ~1,271 signature verifications which is roughly ~1.2 seconds of processing (without optimisations like batched signatures verification). An attacker would need to spend 1,000 ETH to slow down block processing by a second which isn&#x27;t sustainable and viable attack long term.&lt;&#x2F;p&gt;
&lt;p&gt;An optimistically syncing node may be susceptible to a more severe attack scenario. Such a node can&#x27;t validate a list of deposits provided in a payload which makes it possible for attacker to include as many deposits as the limitation allows to. Currently, it is 8,192 deposits (1.5MB of data) with rough processing time of 8s. Considering an attacker would need to sign off on this block with its crypto economically viable signature (which requires building an alternative chain and feeding it to a syncing node), this attack vector is not considered as viable as it can&#x27;t result in a significant slow down of a sync process.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;optimistic-sync&quot;&gt;Optimistic sync&lt;&#x2F;h3&gt;
&lt;p&gt;An optimistically syncing node has to rely on the honest majority assumption. That is, if adversary is powerful enough to finalize a deposit sequence, a syncing node will have to apply these deposits disregarding the validity of deposit requests with respect to the execution of a given block. Thus, an adversary that can finalize an invalid chain can also convince an honest node to accept fake deposits. The same is applicable to the validity of execution layer world state today and a new deposit processing design is within boundaries of the existing security model in that regard.&lt;&#x2F;p&gt;
&lt;p&gt;Online nodes can&#x27;t be tricked into this situation because their execution layer validates supplied deposits with respect to the block execution.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weak-subjectivity-period&quot;&gt;Weak subjectivity period&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP removes a hard limit on a number of deposits per epoch and makes a block gas limit the only limitation on this number. That is, the limit on deposits per epoch shifts from &lt;code&gt;MAX_DEPOSITS * SLOTS_PER_EPOCH = 512&lt;&#x2F;code&gt; to &lt;code&gt;max_deposits_per_30m_gas_block * SLOTS_PER_EPOCH ~ 32,768&lt;&#x2F;code&gt; at 30M gas block (we consider &lt;code&gt;max_deposits_per_30m_gas_block = 1,024&lt;&#x2F;code&gt; for simplicity).&lt;&#x2F;p&gt;
&lt;p&gt;This change affects a number of top ups per epoch which is one of the inputs to the weak subjectivity period computation. One can top up own validators to instantly increase a portion of stake it owns with respect to those validators that are leaking. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6110&#x2F;assets&#x2F;ws_period_analysis&#x2F;&quot;&gt;The analysis&lt;&#x2F;a&gt; does not demonstrate significant reduction of a weak subjectivity period sizes. Moreover, such an attack is not considered as viable because it requires a decent portion of stake to be burned as one of preliminaries.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Guard of NFT&#x2F;SBT, an Extension of ERC-721</title>
        <published>2022-12-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>5660-eth</name><uri>https://github.com/5660-eth</uri>
	</author>
	
	<author>
		<name>Wizard Wang</name>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6147/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/guard-of-nft-sbt-an-extension-of-eip-721/12052" />
        

        <id>https://wg-eips.ritovision.com/6147/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:6147"
            label="ERC-6147" />
        

        
        

        
        <summary type="html">A new management role with an expiration date of NFT&#x2F;SBT is defined, achieving the separation of transfer right and holding right.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6147/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. It separates the holding right and transfer right of non-fungible tokens (NFTs) and Soulbound Tokens (SBTs) and defines a new role, &lt;code&gt;guard&lt;&#x2F;code&gt; with &lt;code&gt;expires&lt;&#x2F;code&gt;. The flexibility of the &lt;code&gt;guard&lt;&#x2F;code&gt; setting enables the design of NFT anti-theft, NFT lending, NFT leasing, SBT, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;NFTs are assets that possess both use and financial value.&lt;&#x2F;p&gt;
&lt;p&gt;Many cases of NFT theft currently exist, and current NFT anti-theft schemes, such as transferring NFTs to cold wallets, make NFTs inconvenient to be used.&lt;&#x2F;p&gt;
&lt;p&gt;In current NFT lending, the NFT owner needs to transfer the NFT to the NFT lending contract, and the NFT owner no longer has the right to use the NFT while he has obtained the loan. In the real world, for example, if a person takes out a mortgage on his own house, he still has the right to use that house.&lt;&#x2F;p&gt;
&lt;p&gt;For SBT, the current mainstream view is that an SBT is not transferable, which makes an SBT bound to an Ether address. However, when the private key of the user address is leaked or lost, retrieving SBT will become a complicated task and there is no corresponding standard. The SBTs essentially realizes the separation of NFT holding right and transfer right. When the wallet where SBT is located is stolen or unavailable, SBT should be able to be recoverable.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, SBTs still need to be managed in use. For example, if a university issues diploma-based SBTs to its graduates, and if the university later finds that a graduate has committed academic misconduct or jeopardized the reputation of the university, it should have the ability to retrieve the diploma-based SBTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-721 compliant contracts MAY implement this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;A guard Must be valid only before expires.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has no guard or the guard is expired, &lt;code&gt;guardInfo&lt;&#x2F;code&gt; MUST return &lt;code&gt;(address(0), 0)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has no guard or the guard is expired, owner, authorised operators and approved address of the token MUST have permission to set guard and expires.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has a valid guard, owner, authorised operators and approved address of the token MUST NOT be able to change guard and expires, and they MUST NOT be able to transfer the token.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has a valid guard, &lt;code&gt;guardInfo&lt;&#x2F;code&gt; MUST return the address and expires of the guard.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has a valid guard, the guard MUST be able to remove guard and expires, change guard and expires, and transfer the token.&lt;&#x2F;p&gt;
&lt;p&gt;When a token has a valid guard, if the token burns, the guard MUST be deleted.&lt;&#x2F;p&gt;
&lt;p&gt;If issuing or minting SBTs, the guard MAY be uniformly set to the designated address to facilitate management.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6147&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Logged when the guard of an NFT is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or expires is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the `guard` is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or the `expires` is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         The zero address for `newGuard` indicates that there currently is no guard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateGuardLog&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldGuard&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner, authorised operators and approved address of the NFT can set guard and expires of the NFT and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         valid guard can modifiy guard and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         If the NFT has a valid guard role, the owner, authorised operators and approved address of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         cannot modify guard and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `newGuard` can not be zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The `expires` need to be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the guard address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new guard address of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp, the guard could manage the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; changeGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the guard and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Only guard can remove its own guard role and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The guard address is set to 0 address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The expires is set to 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to remove the guard and expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer the NFT and remove its guard and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT is transferred to `to` and the guard address is set to 0 address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the previous owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of NFT recipient &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get transferred for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAndRemove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the guard address and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates that there is no guard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the guard address and expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; guard address and expires for the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; guardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;changeGuard(uint256 tokenId, address newGuard, uint64 expires)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;removeGuard(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;transferAndRemove(address from,address to,uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;guardInfo(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;UpdateGuardLog&lt;&#x2F;code&gt; event MUST be emitted when a guard is changed.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0xb61d1057&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;universality&quot;&gt;Universality&lt;&#x2F;h3&gt;
&lt;p&gt;There are many application scenarios for NFT&#x2F;SBT, and there is no need to propose a dedicated EIP for each one, which would make the overall number of EIPS inevitably increase and add to the burden of developers. The standard is based on the analysis of the right attached to assets in the real world, and abstracts the right attached to NFT&#x2F;SBT into holding right and transfer right making the standard more universal.&lt;&#x2F;p&gt;
&lt;p&gt;For example, the standard has more than the following use cases:&lt;&#x2F;p&gt;
&lt;p&gt;SBTs. The SBTs issuer can assign a uniform role of &lt;code&gt;guard&lt;&#x2F;code&gt; to the SBTs before they are minted, so that the SBTs cannot be transferred by the corresponding holders and can be managed by the SBTs issuer through the &lt;code&gt;guard&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;NFT anti-theft. If an NFT holder sets a &lt;code&gt;guard&lt;&#x2F;code&gt; address of an NFT as his or her own cold wallet address, the NFT can still be used by the NFT holder, but the risk of theft is greatly reduced.&lt;&#x2F;p&gt;
&lt;p&gt;NFT lending. The borrower sets the &lt;code&gt;guard&lt;&#x2F;code&gt; of his or her own NFT as the lender&#x27;s address, the borrower still has the right to use the NFT while obtaining the loan, but at the same time cannot transfer or sell the NFT. If the borrower defaults on the loan, the lender can transfer and sell the NFT.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, by setting an &lt;code&gt;expires&lt;&#x2F;code&gt; for the &lt;code&gt;guard&lt;&#x2F;code&gt;, the scalability of the protocol is further enhanced, as demonstrated in the following examples:&lt;&#x2F;p&gt;
&lt;p&gt;More flexible NFT issuance. During NFT minting, discounts can be offered for NFTs that are locked for a certain period of time, without affecting the NFTs&#x27; usability.&lt;&#x2F;p&gt;
&lt;p&gt;More secure NFT management. Even if the &lt;code&gt;guard&lt;&#x2F;code&gt; address becomes inaccessible due to lost private keys, the &lt;code&gt;owner&lt;&#x2F;code&gt; can still retrieve the NFT after the &lt;code&gt;guard&lt;&#x2F;code&gt; has expired.&lt;&#x2F;p&gt;
&lt;p&gt;Valid SBTs. Some SBTs have a period of use. More effective management can be achieved through &lt;code&gt;guard&lt;&#x2F;code&gt; and &lt;code&gt;expires&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extensibility&quot;&gt;Extensibility&lt;&#x2F;h3&gt;
&lt;p&gt;This standard only defines a &lt;code&gt;guard&lt;&#x2F;code&gt; and its &lt;code&gt;expires&lt;&#x2F;code&gt;. For complex functions needed by NFTs and SBTs, such as social recovery and multi-signature, the &lt;code&gt;guard&lt;&#x2F;code&gt; can be set as a third-party protocol address. Through the third-party protocol, more flexible and diverse functions can be achieved based on specific application scenarios.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;naming&quot;&gt;Naming&lt;&#x2F;h3&gt;
&lt;p&gt;The alternative names are &lt;code&gt;guardian&lt;&#x2F;code&gt; and &lt;code&gt;guard&lt;&#x2F;code&gt;, both of which basically match the permissions corresponding to the role: protection of NFT or necessary management according to its application scenarios. The &lt;code&gt;guard&lt;&#x2F;code&gt; has fewer characters than the &lt;code&gt;guardian&lt;&#x2F;code&gt; and is more concise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard can be fully ERC-721 compatible by adding an extension function set.&lt;&#x2F;p&gt;
&lt;p&gt;If an NFT issued based on the above standard does not set a &lt;code&gt;guard&lt;&#x2F;code&gt;, then it is no different in the existing functions from the current NFT issued based on the ERC-721 standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC6147.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;abstract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6147&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC6147&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A structure representing a token of guard address and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; guard&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of guard role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expirs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp, the guard could manage the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GuardInfo&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&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;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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; GuardInfo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; _guardInfo&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Owner, authorised operators and approved address of the NFT can set guard and expires of the NFT and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         valid guard can modifiy guard and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         If the NFT has a valid guard role, the owner, authorised operators and approved address of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         cannot modify guard and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `newGuard` can not be zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The `expires` need to be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the guard address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new guard address of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp, the guard could manage the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; changeGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6147: invalid expires&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _updateGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the guard and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Only guard can remove its own guard role and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The guard address is set to 0 address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The expires is set to 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to remove the guard and expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        _updateGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer the NFT and remove its guard and expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT is transferred to `to` and the guard address is set to 0 address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the previous owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of NFT recipient &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get transferred for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAndRemove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        removeGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the guard address and expires of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates that there is no guard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the guard address and expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; guard address and expires for the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; guardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_guardInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_guardInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _guardInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Update the guard of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Delete function: set guard to 0 address and set expires to 0; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      and update function: set guard to new address and set expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to update the guard address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The newGuard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNIX timestamp, the guard could manage the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; allowNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allow 0 address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _updateGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; allowNull&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; guardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;allowNull&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newGuard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6147: new guard can not be null&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6147: only guard can change it self&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6147: caller is not owner nor approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; newGuard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;            _guardInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GuardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;expires&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateGuardLog&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newGuard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check the guard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no guard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to check the guard address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; guard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _checkGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; guardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6147: sender is not guard of the token&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&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;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Before transferring the NFT, need to check the gurard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; new_from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;            guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _checkGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;            new_from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;                _isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                &amp;quot;ERC721: transfer caller is not owner nor approved&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;new_from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Before safe transferring the NFT, need to check the gurard address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; new_from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;            guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _checkGuard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;            new_from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;guard &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;                _isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;                &amp;quot;ERC721: transfer caller is not owner nor approved&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _safeTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _data&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When burning, delete `token_guard_map[tokenId]`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is an internal function that does not check if the sender is authorized to operate on the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;guardInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        delete&lt;&#x2F;span&gt;&lt;span&gt; _guardInfo&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateGuardLog&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; guard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC165-supportsInterface}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC6147&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Make sure to set an appropriate &lt;code&gt;expires&lt;&#x2F;code&gt; for the &lt;code&gt;guard&lt;&#x2F;code&gt;, based on the specific application scenario.&lt;&#x2F;p&gt;
&lt;p&gt;When an NFT has a valid guard, even if an address is authorized as an operator through &lt;code&gt;approve&lt;&#x2F;code&gt; or &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt;, the operator still has no right to transfer the NFT.&lt;&#x2F;p&gt;
&lt;p&gt;When an NFT has a valid guard, the &lt;code&gt;owner&lt;&#x2F;code&gt; cannot sell the NFT. Some trading platforms list NFTs through &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; and owners&#x27; signature. It is recommended to prevent listing these NFTs by checking &lt;code&gt;guardInfo&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Custom errors for commonly-used tokens</title>
        <published>2022-12-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ernesto García</name><uri>https://github.com/ernestognw</uri>
	</author>
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6093/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6093-custom-errors-for-erc-tokens/12043" />
        

        <id>https://wg-eips.ritovision.com/6093/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6093"
            label="ERC-6093" />
        

        
        

        
        <summary type="html">Lists custom errors for common token implementations</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6093/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a standard set of custom errors for commonly-used tokens, which are defined as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Ethereum applications and wallets have historically relied on revert reason strings to display the cause of transaction errors to users. Recent Solidity versions offer rich revert reasons with error-specific decoding (sometimes called &quot;custom errors&quot;). This EIP defines a standard set of errors designed to give at least the same relevant information as revert reason strings, but in a structured and expected way that clients can implement decoding for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Since the introduction of Solidity custom errors in v0.8.4, these have provided a way to show failures in a more expressive and gas efficient manner with dynamic arguments, while reducing deployment costs.&lt;&#x2F;p&gt;
&lt;p&gt;However, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; were already finalized when custom errors were released, so no errors are included in their specification.&lt;&#x2F;p&gt;
&lt;p&gt;Standardized errors allow users to expect more consistent error messages across applications or testing environments, while exposing pertinent arguments and overall reducing the need of writing expensive revert strings in the deployment bytecode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;The following errors were designed according to the criteria described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#rationale&quot;&gt;Rationale&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP defines standard errors that may be used by implementations in certain scenarios but it does not specify whether implementations should revert in those scenarios, which remains up to the implementers unless a revert is mandated by the corresponding EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;The names of the error arguments are defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#parameter-glossary&quot;&gt;Parameter Glossary&lt;&#x2F;a&gt; and MUST be used according to those definitions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-20&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc20insufficientbalance-address-sender-uint256-balance-uint256-needed&quot;&gt;&lt;code&gt;ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates an error related to the current &lt;code&gt;balance&lt;&#x2F;code&gt; of a &lt;code&gt;sender&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balance&lt;&#x2F;code&gt; MUST be less than &lt;code&gt;needed&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc20invalidsender-address-sender&quot;&gt;&lt;code&gt;ERC20InvalidSender(address sender)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;sender&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for balance or allowance requirements.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC20InsufficientBalance&lt;&#x2F;code&gt; or &lt;code&gt;ERC20InsufficientAllowance&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc20invalidreceiver-address-receiver&quot;&gt;&lt;code&gt;ERC20InvalidReceiver(address receiver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;receiver&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to non-compatible addresses (eg. contract addresses).&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc20insufficientallowance-address-spender-uint256-allowance-uint256-needed&quot;&gt;&lt;code&gt;ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;spender&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;allowance&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;allowance&lt;&#x2F;code&gt; MUST be less than &lt;code&gt;needed&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc20invalidapprover-address-approver&quot;&gt;&lt;code&gt;ERC20InvalidApprover(address approver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;approver&lt;&#x2F;code&gt; of a token to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc20invalidspender-address-spender&quot;&gt;&lt;code&gt;ERC20InvalidSpender(address spender)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;spender&lt;&#x2F;code&gt; to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals to the owner itself.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC20InsufficientAllowance&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;erc-721&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc721invalidowner-address-owner&quot;&gt;&lt;code&gt;ERC721InvalidOwner(address owner)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates that an address can&#x27;t be an owner.
Used in balance queries.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for addresses whose ownership is disallowed (eg. ERC-721 explicitly disallows &lt;code&gt;address(0)&lt;&#x2F;code&gt; to be an owner).&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfers.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC721IncorrectOwner&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721nonexistenttoken-uint256-tokenid&quot;&gt;&lt;code&gt;ERC721NonexistentToken(uint256 tokenId)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a &lt;code&gt;tokenId&lt;&#x2F;code&gt; whose &lt;code&gt;owner&lt;&#x2F;code&gt; is the zero address.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;tokenId&lt;&#x2F;code&gt; MUST BE a non-minted or burned token.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721incorrectowner-address-sender-uint256-tokenid-address-owner&quot;&gt;&lt;code&gt;ERC721IncorrectOwner(address sender, uint256 tokenId, address owner)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates an error related to the ownership over a particular token.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sender&lt;&#x2F;code&gt; MUST NOT be &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721invalidsender-address-sender&quot;&gt;&lt;code&gt;ERC721InvalidSender(address sender)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;sender&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for ownership or approval requirements.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC721IncorrectOwner&lt;&#x2F;code&gt; or &lt;code&gt;ERC721InsufficientApproval&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721invalidreceiver-address-receiver&quot;&gt;&lt;code&gt;ERC721InvalidReceiver(address receiver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;receiver&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to non-&lt;code&gt;ERC721TokenReceiver&lt;&#x2F;code&gt; contracts or those that reject a transfer. (eg. returning an invalid response in &lt;code&gt;onERC721Received&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721insufficientapproval-address-operator-uint256-tokenid&quot;&gt;&lt;code&gt;ERC721InsufficientApproval(address operator, uint256 tokenId)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;operator&lt;&#x2F;code&gt;&#x27;s approval.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;isApprovedForAll(owner, operator)&lt;&#x2F;code&gt; MUST be false for the &lt;code&gt;tokenId&lt;&#x2F;code&gt;&#x27;s owner and &lt;code&gt;operator&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getApproved(tokenId)&lt;&#x2F;code&gt; MUST not be &lt;code&gt;operator&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721invalidapprover-address-approver&quot;&gt;&lt;code&gt;ERC721InvalidApprover(address approver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;owner&lt;&#x2F;code&gt; of a token to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc721invalidoperator-address-operator&quot;&gt;&lt;code&gt;ERC721InvalidOperator(address operator)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;operator&lt;&#x2F;code&gt; to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;operator&lt;&#x2F;code&gt; MUST NOT be the owner of the approved token.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC721InsufficientApproval&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;erc-1155&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc1155insufficientbalance-address-sender-uint256-balance-uint256-needed-uint256-tokenid&quot;&gt;&lt;code&gt;ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates an error related to the current &lt;code&gt;balance&lt;&#x2F;code&gt; of a &lt;code&gt;sender&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balance&lt;&#x2F;code&gt; MUST be less than &lt;code&gt;needed&lt;&#x2F;code&gt; for a &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155invalidsender-address-sender&quot;&gt;&lt;code&gt;ERC1155InvalidSender(address sender)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;sender&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for balance or allowance requirements.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC1155InsufficientBalance&lt;&#x2F;code&gt; or &lt;code&gt;ERC1155MissingApprovalForAll&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155invalidreceiver-address-receiver&quot;&gt;&lt;code&gt;ERC1155InvalidReceiver(address receiver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the token &lt;code&gt;receiver&lt;&#x2F;code&gt;.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;RECOMMENDED for disallowed transfers to non-&lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; contracts or those that reject a transfer. (eg. returning an invalid response in &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for approval operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155missingapprovalforall-address-operator-address-owner&quot;&gt;&lt;code&gt;ERC1155MissingApprovalForAll(address operator, address owner)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;operator&lt;&#x2F;code&gt;&#x27;s approval in a transfer.
Used in transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;isApprovedForAll(owner, operator)&lt;&#x2F;code&gt; MUST be false for the &lt;code&gt;tokenId&lt;&#x2F;code&gt;&#x27;s owner and &lt;code&gt;operator&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155invalidapprover-address-approver&quot;&gt;&lt;code&gt;ERC1155InvalidApprover(address approver)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;approver&lt;&#x2F;code&gt; of a token to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals from the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155invalidoperator-address-operator&quot;&gt;&lt;code&gt;ERC1155InvalidOperator(address operator)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates a failure with the &lt;code&gt;operator&lt;&#x2F;code&gt; to be approved.
Used in approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RECOMMENDED for disallowed approvals to the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST be used for disallowed approvals to the owner itself.&lt;&#x2F;li&gt;
&lt;li&gt;MUST NOT be used for transfer operations.
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ERC1155InsufficientApproval&lt;&#x2F;code&gt; instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc1155invalidarraylength-uint256-idslength-uint256-valueslength&quot;&gt;&lt;code&gt;ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength)&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Indicates an array length mismatch between &lt;code&gt;ids&lt;&#x2F;code&gt; and &lt;code&gt;values&lt;&#x2F;code&gt; in a &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; operation.
Used in batch transfers.&lt;&#x2F;p&gt;
&lt;p&gt;Usage guidelines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;idsLength&lt;&#x2F;code&gt; MUST NOT be &lt;code&gt;valuesLength&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;parameter-glossary&quot;&gt;Parameter Glossary&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address whose tokens are being transferred.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;balance&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Current balance for the interacting account.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;needed&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Minimum amount required to perform an action.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;receiver&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address to which tokens are being transferred.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;spender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address that may be allowed to operate on tokens without being their owner.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;allowance&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Amount of tokens a &lt;code&gt;spender&lt;&#x2F;code&gt; is allowed to operate with.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;approver&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address initiating an approval operation.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Identifier number of a token.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;owner&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Address of the current owner of a token.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Same as &lt;code&gt;spender&lt;&#x2F;code&gt;.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;*Length&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Array length for the prefixed parameter.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;error-additions&quot;&gt;Error additions&lt;&#x2F;h3&gt;
&lt;p&gt;Any addition to this EIP or implementation-specific errors (such as extensions) SHOULD follow the guidelines presented in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#rationale&quot;&gt;rationale&lt;&#x2F;a&gt; section to keep consistency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The chosen objectives for a standard for token errors are to provide context about the error, and to make moderate use of meaningful arguments (to maintain the code size benefits with respect to strings).&lt;&#x2F;p&gt;
&lt;p&gt;Considering this, the error names are designed following a basic grammatical structure based on the standard actions that can be performed on each token and the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#actions-and-subjects&quot;&gt;subjects&lt;&#x2F;a&gt; involved.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;actions-and-subjects&quot;&gt;Actions and subjects&lt;&#x2F;h3&gt;
&lt;p&gt;An error is defined based on the following &lt;strong&gt;actions&lt;&#x2F;strong&gt; that can be performed on a token and its involved &lt;em&gt;subjects&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transfer&lt;&#x2F;strong&gt;: An operation in which a &lt;em&gt;sender&lt;&#x2F;em&gt; moves to a &lt;em&gt;receiver&lt;&#x2F;em&gt; any number of tokens (fungible &lt;em&gt;balance&lt;&#x2F;em&gt; and&#x2F;or non-fungible &lt;em&gt;token ids&lt;&#x2F;em&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Approval&lt;&#x2F;strong&gt;: An operation in which an &lt;em&gt;approver&lt;&#x2F;em&gt; grants any form of &lt;em&gt;approval&lt;&#x2F;em&gt; to an &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These attempt to exhaustively represent what can go wrong in a token operation. Therefore, the errors can be constructed by specifying which &lt;em&gt;subject&lt;&#x2F;em&gt; failed during an &lt;strong&gt;action&lt;&#x2F;strong&gt; execution, and prefixing with an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#error-prefixes&quot;&gt;error prefix&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the action is never seen as the subject of an error.&lt;&#x2F;p&gt;
&lt;p&gt;If a subject is called different on a particular token standard, the error should be consistent with the standard&#x27;s naming convention.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;error-prefixes&quot;&gt;Error prefixes&lt;&#x2F;h3&gt;
&lt;p&gt;An error prefix is added to a subject to derive a concrete error condition.
Developers can think about an error prefix as the &lt;em&gt;why&lt;&#x2F;em&gt; an error happened.&lt;&#x2F;p&gt;
&lt;p&gt;A prefix can be &lt;code&gt;Invalid&lt;&#x2F;code&gt; for general incorrectness, or more specific like &lt;code&gt;Insufficient&lt;&#x2F;code&gt; for amounts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;domain&quot;&gt;Domain&lt;&#x2F;h3&gt;
&lt;p&gt;Each error&#x27;s arguments may vary depending on the token domain. If there are errors with the same name and different arguments, the Solidity compiler currently fails with a &lt;code&gt;DeclarationError&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An example of this is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;InsufficientApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; needed&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;InsufficientApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&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 that reason, a domain prefix is proposed to avoid declaration clashing, which is the name of the ERC and its corresponding number appended at the beginning.&lt;&#x2F;p&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC20InsufficientApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; needed&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;ERC721InsufficientApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&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;arguments&quot;&gt;Arguments&lt;&#x2F;h3&gt;
&lt;p&gt;The selection of arguments depends on the subject involved, and it should follow the order presented below:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Who&lt;&#x2F;em&gt; is involved with the error (eg. &lt;code&gt;address sender&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;What&lt;&#x2F;em&gt; failed (eg. &lt;code&gt;uint256 allowance&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Why&lt;&#x2F;em&gt; it failed, expressed in additional arguments (eg. &lt;code&gt;uint256 needed&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A particular argument may fall into overlapping categories (eg. &lt;em&gt;Who&lt;&#x2F;em&gt; may also be &lt;em&gt;What&lt;&#x2F;em&gt;), so not all of these will be present but the order shouldn&#x27;t be broken.&lt;&#x2F;p&gt;
&lt;p&gt;Some tokens may need a &lt;code&gt;tokenId&lt;&#x2F;code&gt;. This is suggested to include at the end as additional information instead of as a subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;error-grammar-rules&quot;&gt;Error grammar rules&lt;&#x2F;h3&gt;
&lt;p&gt;Given the above, we can summarize the construction of error names with a grammar that errors will follow:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Domain&amp;gt;&amp;lt;ErrorPrefix&amp;gt;&amp;lt;Subject&amp;gt;(&amp;lt;Arguments&amp;gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Domain&lt;&#x2F;em&gt;: &lt;code&gt;ERC20&lt;&#x2F;code&gt;, &lt;code&gt;ERC721&lt;&#x2F;code&gt; or &lt;code&gt;ERC1155&lt;&#x2F;code&gt;. Although other token standards may be suggested if not considered in this EIP.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;ErrorPrefix&lt;&#x2F;em&gt;: &lt;code&gt;Invalid&lt;&#x2F;code&gt;, &lt;code&gt;Insufficient&lt;&#x2F;code&gt;, or another if it&#x27;s more appropriate.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Subject&lt;&#x2F;em&gt;: &lt;code&gt;Sender&lt;&#x2F;code&gt;, &lt;code&gt;Receiver&lt;&#x2F;code&gt;, &lt;code&gt;Balance&lt;&#x2F;code&gt;, &lt;code&gt;Approver&lt;&#x2F;code&gt;, &lt;code&gt;Operator&lt;&#x2F;code&gt;, &lt;code&gt;Approval&lt;&#x2F;code&gt; or another if it&#x27;s more appropriate, and must make adjustments based on the domain&#x27;s naming convention.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Arguments&lt;&#x2F;em&gt;: Follow the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#arguments&quot;&gt;&lt;em&gt;who&lt;&#x2F;em&gt;, &lt;em&gt;what&lt;&#x2F;em&gt; and &lt;em&gt;why&lt;&#x2F;em&gt; order&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Tokens already deployed rely mostly on revert strings and make use of &lt;code&gt;require&lt;&#x2F;code&gt; instead of custom errors. Even most of the newly deployed tokens since Solidity&#x27;s v0.8.4 release inherit from implementations using revert strings.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP can not be enforced on non-upgradeable already deployed tokens, however, these tokens generally use similar conventions with small variations such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;including&#x2F;removing the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#domain&quot;&gt;domain&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;using different &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#error-prefixes&quot;&gt;error prefixes&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;including similar &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6093&#x2F;#actions-and-subjects&quot;&gt;subjects&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;changing the grammar order.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Upgradeable contracts MAY be upgraded to implement this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers and DApp developers that implement special support for tokens that are compliant with this EIP, SHOULD tolerate different errors emitted by non-compliant contracts, as well as classic revert strings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;solidity&quot;&gt;Solidity&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Standard ERC20 Errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6093&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20Errors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; needed&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InvalidSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InvalidReceiver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InsufficientAllowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; needed&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InvalidApprover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; approver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20InvalidSpender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; spender&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Standard ERC721 Errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6093&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Errors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InvalidOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721NonexistentToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721IncorrectOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InvalidSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InvalidReceiver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InsufficientApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InvalidApprover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; approver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721InvalidOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Standard ERC1155 Errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1155&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6093&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155Errors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; needed&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InvalidSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InvalidReceiver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; receiver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155MissingApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InvalidApprover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; approver&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InvalidOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155InvalidArrayLength&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; idsLength&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; valuesLength&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no known signature hash collisions for the specified errors.&lt;&#x2F;p&gt;
&lt;p&gt;Tokens upgraded to implement this EIP may break assumptions in other systems relying on revert strings.&lt;&#x2F;p&gt;
&lt;p&gt;Offchain applications should be cautious when dealing with untrusted contracts that may revert using these custom errors. For instance, if a user interface prompts actions based on error decoding, malicious contracts could exploit this to encourage untrusted and potentially harmful operations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>No Intermediary NFT Trading Protocol</title>
        <published>2022-12-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>5660-eth</name><uri>https://github.com/5660-eth</uri>
	</author>
	
	<author>
		<name>Silvere Heraudeau</name><uri>https://github.com/lambdalf-dev</uri>
	</author>
	
	<author>
		<name>Martin McConnell</name><uri>https://github.com/offgridgecko</uri>
	</author>
	
	<author>
		<name>Abu</name><email>team10kuni@gmail.com</email>
	</author>
	
	<author>
		<name>Wizard Wang</name>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6105/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip6105-no-intermediary-nft-trading-protocol/12171" />
        

        <id>https://wg-eips.ritovision.com/6105/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:6105"
            label="ERC-6105" />
        

        
        

        
        <summary type="html">Adds a marketplace functionality with more diverse royalty schemes to ERC-721</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6105/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC adds a marketplace functionality to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; to enable non-fungible token trading without relying on an intermediary trading platform. At the same time, creators may implement more diverse royalty schemes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Most current NFT trading relies on an NFT trading platform acting as an intermediary, which has the following problems:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Security concerns arise from authorization via the &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; function. The permissions granted to NFT trading platforms expose unnecessary risks. Should a problem occur with the trading platform contract, it would result in significant losses to the industry as a whole. Additionally, if a user has authorized the trading platform to handle their NFTs, it allows a phishing scam to trick the user into signing a message that allows the scammer to place an order at a low price on the NFT trading platform and designate themselves as the recipient. This can be difficult for ordinary users to guard against.&lt;&#x2F;li&gt;
&lt;li&gt;High trading costs are a significant issue. On one hand, as the number of trading platforms increases, the liquidity of NFTs becomes dispersed. If a user needs to make a deal quickly, they must authorize and place orders on multiple platforms, which increases the risk exposure and requires additional gas expenditures for each authorization. For example, taking BAYC as an example, with a total supply of 10,000 and over 6,000 current holders, the average number of BAYC held by each holder is less than 2. While &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; saves on gas expenditure for pending orders on a single platform, authorizing multiple platforms results in an overall increase in gas expenditures for users. On the other hand, trading service fees charged by trading platforms must also be considered as a cost of trading, which are often much higher than the required gas expenditures for authorization.&lt;&#x2F;li&gt;
&lt;li&gt;Aggregators provide a solution by aggregating liquidity, but the decision-making process is centralized. Furthermore, as order information on trading platforms is off-chain, the aggregator&#x27;s efficiency in obtaining data is affected by the frequency of the trading platform&#x27;s API and, at times, trading platforms may suspend the distribution of APIs and limit their frequency.&lt;&#x2F;li&gt;
&lt;li&gt;The project parties&#x27; royalty income is dependent on centralized decision-making by NFT trading platforms. Some trading platforms implement optional royalty without the consent of project parties, which is a violation of their interests.&lt;&#x2F;li&gt;
&lt;li&gt;NFT trading platforms are not resistant to censorship. Some platforms have delisted a number of NFTs and the formulation and implementation of delisting rules are centralized and not transparent enough. In the past, some NFT trading platforms have failed and wrongly delisted certain NFTs, leading to market panic.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL
NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;,
and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119
and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;Compliant contracts MUST implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6105&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token is listed for sale or delisted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero `salePrice` indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero `expires` indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who is selling the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Additional price parameter, may be used when calculating royalties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; benchmarkPrice&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token is being purchased&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being purchased&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who is selling the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who is buying the token &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; royalties&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The amount of royalties paid on this purchase&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Purchased&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; royalties&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update a listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `salePrice` must not be zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `expires` must be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateListing} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update a listing for `tokenId` with `benchmarkPrice`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Additional price parameter, may be used when calculating royalties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `salePrice` must not be zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `expires` must be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateListing} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; benchmarkPrice&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 class=&quot;z-storage z-type&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being delisted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be listed for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateListing} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delistItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Buy a token and transfer it to the caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being purchased&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be listed for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `salePrice` must matches the expected purchase price to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `supportedToken` must matches the expected purchase token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be able to pay the listed price for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit a {Purchased} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; buyItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return the listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero sale price indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero expires indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero supported token address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identifier of the token being queried&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; specified listing (sale price, expires, supported token, benchmark price)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-collection-offer-extension&quot;&gt;Optional collection offer extension&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The collection offer extension is OPTIONAL for ERC-6105 smart contracts. This allows smart contract to support collection offer functionality.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6105CollectionOffer&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the collection receives an offer or an offer is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero `salePrice` indicates that the collection offer of the token is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero `expires` indicates that the collection offer of the token is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who make collection offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the amount the offerer wants to buy at `salePrice` per token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price of each token is being offered for the collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the offer could be accepted before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported ERC20 token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                          Buyer wants to purchase items with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt; ,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update an offer for the collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the amount the offerer wants to buy at `salePrice` per token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price of each token is being offered for the collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the offer could be accepted before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer wants to purchase items with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The caller must have enough supported tokens, and has approved the contract a sufficient amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `salePrice` must not be zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `amount` must not be zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `expires` must be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateCollectionOffer} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; makeCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Accepts collection offer and transfers the token to the buyer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When the trading is completed, the `amount` of NFTs the buyer wants to purchase needs to be reduced by 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit a {Purchased} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Accepts collection offer and transfers the token to the buyer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When the trading is completed, the `amount` of NFTs the buyer wants to purchase needs to be reduced by 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - additional price parameter, may be used when calculating royalties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit a {Purchased} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Removes the offer for the collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be the offerer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateCollectionOffer} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cancelCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the offer for `tokenId` maked by `buyer`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero amount indicates there is no offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero sale price indicates there is no offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero expires indicates that there is no offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; specified offer (amount, sale price, expires, supported token)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getCollectionOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-item-offer-extension&quot;&gt;Optional item offer extension&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The item offer extension is OPTIONAL for ERC-6105 smart contracts. This allows smart contract to support item offer functionality.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6105ItemOffer&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token receives an offer or an offer is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero `salePrice` indicates that the offer of the token is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero `expires` indicates that the offer of the token is canceled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the offer could be accepted before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                          Buyer wants to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update an offer for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the offer could be accepted before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer wants to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The caller must have enough supported tokens, and has approved the contract a sufficient amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `salePrice` must not be zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `expires` must be valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateItemOffer} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; makeItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the offer for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being canceled offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be the offerer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit an {UpdateItemOffer} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; cancelItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Accept offer and transfer the token to the buyer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When the trading is completed, the offer infomation needs to be removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit a {Purchased} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Accepts offer and transfers the token to the buyer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When the trading is completed, the offer infomation needs to be removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being offered&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - additional price parameter, may be used when calculating royalties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `tokenId` must exist and be offered for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Caller must be owner, authorised operators or approved address of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - Must emit a {Purchased} event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; benchmarkPrice&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return the offer for `tokenId` maked by `buyer`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero sale price indicates there is no offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero expires indicates that there is no offer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identifier of the token being queried&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of who wants to buy the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; specified offer (sale price, expires, supported token)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getItemOffer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;considerations-for-some-local-variables&quot;&gt;Considerations for some local variables&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;salePrice&lt;&#x2F;code&gt; in the &lt;code&gt;listItem&lt;&#x2F;code&gt; function cannot be set to zero. Firstly, it is a rare occurrence for a caller to set the price to 0, and when it happens, it is often due to an operational error which can result in loss of assets. Secondly, a caller needs to spend gas to call this function, so if he can set the token price to 0, his income would be actually negative at this time, which does not conform to the concept of &#x27;economic man&#x27; in economics. Additionally, a token price of 0 indicates that the item is not for sale, making the reference implementation more concise.&lt;&#x2F;p&gt;
&lt;p&gt;Setting &lt;code&gt;expires&lt;&#x2F;code&gt; in the &lt;code&gt;listItem&lt;&#x2F;code&gt; function allows callers to better manage their listings. If a listing expires automatically, the token owner will no longer need to manually &lt;code&gt;delistItem&lt;&#x2F;code&gt;, thus saving gas.&lt;&#x2F;p&gt;
&lt;p&gt;Setting &lt;code&gt;supportedToken&lt;&#x2F;code&gt; in the &lt;code&gt;listItem&lt;&#x2F;code&gt; function allows the caller or contract owner to choose which tokens they want to accept, rather than being limited to a single token.&lt;&#x2F;p&gt;
&lt;p&gt;The rationales of variable setting in the &lt;code&gt;acceptCollectionOffer&lt;&#x2F;code&gt; and &lt;code&gt;acceptItemOffer&lt;&#x2F;code&gt; functions are the same as described above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;more-diverse-royalty-schemes&quot;&gt;More diverse royalty schemes&lt;&#x2F;h3&gt;
&lt;p&gt;By introducing the parameter &lt;code&gt;benchmarkPrice&lt;&#x2F;code&gt; in the &lt;code&gt;listItem&lt;&#x2F;code&gt;, &lt;code&gt;acceptCollectionOffer&lt;&#x2F;code&gt; and &lt;code&gt;acceptItemOffer&lt;&#x2F;code&gt; functions, the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; in the &lt;code&gt;royaltyInfo(uint256 _tokenId, uint256 _salePrice)&lt;&#x2F;code&gt; function in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2981&#x2F;&quot;&gt;ERC-2981&lt;&#x2F;a&gt; interface can be changed to &lt;code&gt;taxablePrice&lt;&#x2F;code&gt;, making the ERC-2981 royalty scheme more diverse. Here are several examples of royalty schemes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;(address royaltyRecipient, uint256 royalties) = royaltyInfo(tokenId, taxablePrice)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Value-added Royalty (VAR, royalties are only charged on the part of the seller&#x27;s profit）: &lt;code&gt;taxablePrice=max(salePrice- historicalPrice, 0)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Sale Royalty (SR): &lt;code&gt;taxablePrice=salePrice&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Capped Royalty(CR): &lt;code&gt;taxablePrice=min(salePrice, constant)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Quantitative Royalty(QR, each token trading pays a fixed royalties): &lt;code&gt;taxablePrice= constant&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;optional-blocklist&quot;&gt;Optional Blocklist&lt;&#x2F;h3&gt;
&lt;p&gt;Some viewpoints suggest that tokens should be prevented from trading on intermediary markets that do not comply with royalty schemes, but this standard only provides a functionality for non-intermediary NFT trading and does not offer a standardized interface to prevent tokens from trading on these markets. If deemed necessary to better protect the interests of the project team and community, they may consider adding a blocklist to their implementation contracts to prevent NFTs from being traded on platforms that do not comply with the project’s royalty scheme.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2981&#x2F;&quot;&gt;ERC-2981&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;security&#x2F;ReentrancyGuard.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC6105.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; No Intermediary NFT Trading Protocol with Value-added Royalty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The royalty scheme used by this reference implementation is Value-Added Royalty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC6105&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC2981&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC6105&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ReentrancyGuard&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A structure representing a listed token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero `salePrice` indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero `expires` indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported ERC20 token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The price at which the seller last bought this token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Listing&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mapping from token Id to listing index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Listing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update a listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported ERC20 token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listItem&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        listItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Create or update a listing for `tokenId` with `historicalPrice`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `price` MUST NOT be set to zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - UNIX timestamp, the buyer could buy the token before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported ERC20 token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         Buyer needs to purchase item with supported token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - The price at which the seller last bought this token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listItem&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; historicalPrice&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: token sale price MUST NOT be set to zero&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: invalid expires&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: caller is not owner nor approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Listing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being listed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delistItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: caller is not owner nor approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isForSale&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: invalid listing&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    _removeListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Buy a token and transfers it to the caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `salePrice` and `supportedToken` must match the expected purchase price and token to prevent front-running attacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being purchased&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the price the token is being sold for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; buyItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nonReentrant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; buyer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;historicalPrice&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: inconsistent prices&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;supportedToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt;  _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC6105: inconsistent tokens&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isForSale&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: invalid listing&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle royalties&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 class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; royaltyRecipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; royalties&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _calculateRoyalties&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; payment &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; royalties&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;supportedToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: incorrect value&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _processSupportedTokenPayment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;royalties&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; royaltyRecipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _processSupportedTokenPayment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;payment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; num &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;num &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC6105: insufficient allowance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _processSupportedTokenPayment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;royalties&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; royaltyRecipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _processSupportedTokenPayment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;payment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-entity z-name&quot;&gt;    _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Purchased&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; royalties&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return the listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero sale price indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero expires indicates that the token is not for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The zero supported token address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identifier of the token being queried&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; specified listing (sale price, expires, supported token, benchmark price)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;  block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;salePrice&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint64&lt;&#x2F;span&gt;&lt;span&gt; expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; supportedToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;  _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;supportedToken&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;historicalPrice&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;salePrice&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; supportedToken&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remove the listing for `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - identifier of the token being delisted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _removeListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    delete&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if the token is for sale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _isForSale&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;salePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; _listings&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle Value Added Royalty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _calculateRoyalties&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; price&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; historicalPrice&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; taxablePrice&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;price &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&gt;&lt;span&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&gt;      taxablePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; price &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; historicalPrice&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;      taxablePrice &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; royaltyRecipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; royalties&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; royaltyInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; taxablePrice&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;royaltyRecipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; royalties&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Process a `supportedToken` of `amount` payment to `recipient`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the amount to send&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the payment payer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the payment recipient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; supportedToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - contract addresses of supported ERC20 token or zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         The zero address indicates that the supported token is ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _processSupportedTokenPayment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; supportedToken&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;supportedToken &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;recipient&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Ether Transfer Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;supportedToken&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Supported Token Transfer Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC165-supportsInterface}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC2981&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;     return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC6105&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Before transferring the NFT, need to delete listing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; batchSize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-variable z-language&quot;&gt;      super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; batchSize&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isForSale&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;          _removeListing&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;buyItem&lt;&#x2F;code&gt; function, as well as the &lt;code&gt;acceptCollectionOffer&lt;&#x2F;code&gt; and &lt;code&gt;acceptItemOffer&lt;&#x2F;code&gt; functions, has a potential front-running risk.  Must check that &lt;code&gt;salePrice&lt;&#x2F;code&gt; and &lt;code&gt;supportedToken&lt;&#x2F;code&gt; match the expected price and token to prevent front-running attacks&lt;&#x2F;p&gt;
&lt;p&gt;There is a potential re-entrancy risk with the &lt;code&gt;acceptCollectionOffer&lt;&#x2F;code&gt; and &lt;code&gt;acceptItemOffer&lt;&#x2F;code&gt; functions. Make sure to obey the checks, effects, interactions pattern or use a reentrancy guard.&lt;&#x2F;p&gt;
&lt;p&gt;If a buyer uses &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens to purchase an NFT, the buyer needs to first call the &lt;code&gt;approve(address spender, uint256 amount)&lt;&#x2F;code&gt; function of the ERC-20 token to grant the NFT contract access to a certain &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens. Please make sure to authorize an appropriate &lt;code&gt;amount&lt;&#x2F;code&gt;. Furthermore, caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Signature Validation Method for NFTs</title>
        <published>2022-11-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Jack Boyuan Xu</name><uri>https://github.com/boyuanx</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6066/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6066-signature-validation-method-for-nfts/11943" />
        

        <id>https://wg-eips.ritovision.com/6066/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6066"
            label="ERC-6066" />
        

        
        

        
        <summary type="html">A way to verify signatures when the signing entity is an ERC-721 or ERC-1155 NFT</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6066/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;While &lt;strong&gt;E&lt;&#x2F;strong&gt;xternally &lt;strong&gt;O&lt;&#x2F;strong&gt;wned &lt;strong&gt;A&lt;&#x2F;strong&gt;ccounts can validate signed messages with &lt;code&gt;ecrecover()&lt;&#x2F;code&gt; and smart contracts can validate signatures using specifications outlined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;, currently there is no standard method to create or validate signatures made by NFTs. We propose a standard way for anyone to validate whether a signature made by an NFT is valid. This is possible via a modified signature validation function originally found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt;: &lt;code&gt;isValidSignature(tokenId, hash, data)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With billions of ETH in trading volume, the &lt;strong&gt;N&lt;&#x2F;strong&gt;on-&lt;strong&gt;F&lt;&#x2F;strong&gt;ungible &lt;strong&gt;T&lt;&#x2F;strong&gt;oken standard has exploded into tremendous popularity in recent years. Despite the far-reaching implications of having unique tokenized items on-chain, NFTs have mainly been used to represent artwork in the form of avatars or profile pictures. While this is certainly not a trivial use case for the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; &amp;amp; &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; token standards, we reckon more can be done to aid the community in discovering alternative uses for NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;One of the alternative use cases for NFTs is using them to represent offices in an organization. In this case, tying signatures to transferrable NFTs instead of EOAs or smart contracts becomes crucial. Suppose there exists a DAO that utilizes NFTs as badges that represent certain administrative offices (i.e., CEO, COO, CFO, etc.) with a quarterly democratic election that potentially replaces those who currently occupy said offices. If the sitting COO has previously signed agreements or authorized certain actions, their past signatures would stay with the EOA who used to be the COO instead of the COO&#x27;s office itself once they are replaced with another EOA as the new COO-elect. Although a multisig wallet for the entire DAO is one way to mitigate this problem, often it is helpful to generate signatures on a more intricate level so detailed separation of responsibilities are established and maintained. It is also feasible to appoint a smart contract instead of an EOA as the COO, but the complexities this solution brings are unnecessary. If a DAO uses ENS to establish their organizational hierarchy, this proposal would allow wrapped ENS subdomains (which are NFTs) to generate signatures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.8.0;&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;interface IERC6066 {&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;     * @dev MUST return if the signature provided is valid for the provided tokenId and hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param tokenId   Token ID of the signing NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param hash      Hash of the data to be signed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param data      OPTIONAL arbitrary data that may aid verification&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;     * MUST return the bytes4 magic value 0x12edb34f when function passes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * MUST NOT modify state (using STATICCALL for solc &amp;lt; 0.5, view modifier for solc &amp;gt; 0.5)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * MUST allow external calls&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;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function isValidSignature(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes32 hash,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view returns (bytes4 magicValue);&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;&lt;code&gt;isValidSignature&lt;&#x2F;code&gt; can call arbitrary methods to validate a given signature.&lt;&#x2F;p&gt;
&lt;p&gt;This function MAY be implemented by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; compliant contracts that desire to enable its token holders to sign messages using their NFTs. Compliant callers wanting to support contract signatures MUST call this method if the signer is the holder of an NFT (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;We have purposefully decided to not include a signature generation standard in this proposal as it would restrict flexibility of such mechanism, just as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; does not enforce a signing standard for smart contracts. We also decided to reference Gnosis Safe&#x27;s contract signing approach as it is both simplistic and proven to be adequate. The &lt;code&gt;bytes calldata data&lt;&#x2F;code&gt; parameter is considered optional if extra data is needed for signature verification, also conforming this EIP to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5750&#x2F;&quot;&gt;ERC-5750&lt;&#x2F;a&gt; for future-proofing purposes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is incompatible with previous work on signature validation as it does not validate any cryptographically generated signatures. Instead, signature is merely a boolean flag indicating consent. This is consistent with Gnosis Safe&#x27;s contract signature implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Example implementation of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; compliant contract that conforms to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6066&#x2F;&quot;&gt;ERC-6066&lt;&#x2F;a&gt; with a custom signing function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.8.0;&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;import &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;ERC721.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;.&#x2F;interfaces&#x2F;IERC6066.sol&amp;quot;;&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;contract ERC6066Reference is ERC721, IERC6066 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; type(IERC6066).interfaceId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes4 public constant MAGICVALUE = 0x12edb34f;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes4 public constant BADVALUE = 0xffffffff;&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;    mapping(uint256 =&amp;gt; mapping(bytes32 =&amp;gt; bool)) internal _signatures;&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;    error ENotTokenOwner();&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Checks if the sender owns NFT with ID tokenId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param tokenId   Token ID of the signing NFT&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;    modifier onlyTokenOwner(uint256 tokenId) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (ownerOf(tokenId) != _msgSender()) revert ENotTokenOwner();&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constructor(string memory name_, string memory symbol_)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ERC721(name_, symbol_)&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev SHOULD sign the provided hash with NFT of tokenId given sender owns said NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param tokenId   Token ID of the signing NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param hash      Hash of the data to be signed&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;    function sign(uint256 tokenId, bytes32 hash)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        onlyTokenOwner(tokenId)&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;        _signatures[tokenId][hash] = true;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev MUST return if the signature provided is valid for the provided tokenId, hash, and optionally data&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;    function isValidSignature(uint256 tokenId, bytes32 hash, bytes calldata data)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        override&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        returns (bytes4 magicValue)&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;        &#x2F;&#x2F; The data parameter is unused in this example&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return _signatures[tokenId][hash] ? MAGICVALUE : BADVALUE;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev ERC-165 support&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;    function supportsInterface(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes4 interfaceId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) public view virtual override returns (bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            interfaceId == type(IERC6066).interfaceId ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            super.supportsInterface(interfaceId);&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The revokable nature of contract-based signatures carries over to this EIP. Developers and users alike should take it into consideration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Deprecate SELFDESTRUCT</title>
        <published>2022-11-27T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>William Entriken</name><uri>https://github.com/fulldecent</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6049/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/deprecate-selfdestruct/11907" />
        

        <id>https://wg-eips.ritovision.com/6049/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:6049"
            label="EIP-6049" />
        

        
        

        
        <summary type="html">Deprecate SELFDESTRUCT by discouraging its use and warning about a potential future behavior change.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6049/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP deprecates the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode and warns against its use. A breaking change to this functionality is likely to come in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Discussions about how to change &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; are ongoing. But there is a strong consensus that &lt;em&gt;something&lt;&#x2F;em&gt; will change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Documentation of the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode is updated to warn against its use and to note that a breaking change may be forthcoming.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;As time goes on, the cost of doing something increases, because any change to &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; will be a breaking change.&lt;&#x2F;p&gt;
&lt;p&gt;The Ethereum Blog and other official sources have not provided any warning to developers about a potential forthcoming change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP updates non-normative text in the Yellow Paper. No changes to clients is applicable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Parent-Governed Nestable Non-Fungible Tokens</title>
        <published>2022-11-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Cicada</name><uri>https://github.com/CicadaNCR</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6059/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-6059-parent-governed-nestable-non-fungible-tokens/11914" />
        

        <id>https://wg-eips.ritovision.com/6059/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:6059"
            label="ERC-6059" />
        

        
        

        
        <summary type="html">An interface for Nestable Non-Fungible Tokens with emphasis on parent token&#x27;s control over the relationship.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6059/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Parent-Governed Nestable NFT standard extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; by allowing for a new inter-NFT relationship and interaction.&lt;&#x2F;p&gt;
&lt;p&gt;At its core, the idea behind the proposal is simple: the owner of an NFT does not have to be an Externally Owned Account (EOA) or a smart contract, it can also be an NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The process of nesting an NFT into another is functionally identical to sending it to another user. The process of sending a token out of another one involves issuing a transaction from the account owning the parent token.&lt;&#x2F;p&gt;
&lt;p&gt;An NFT can be owned by a single other NFT, but can in turn have a number of NFTs that it owns. This proposal establishes the framework for the parent-child relationships of NFTs. A parent token is the one that owns another token. A child token is a token that is owned by another token. A token can be both a parent and child at the same time. Child tokens of a given token can be fully managed by the parent token&#x27;s owner, but can be proposed by anyone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-nestable-tokens.png&quot; alt=&quot;Nestable tokens&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The graph illustrates how a child token can also be a parent token, but both are still administered by the root parent token&#x27;s owner.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability for tokens to own other tokens allows for greater utility, usability and forward compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;In the four years since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; was published, the need for additional functionality has resulted in countless extensions. This ERC improves upon ERC-721 in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;#bundling&quot;&gt;Bundling&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;#collecting&quot;&gt;Collecting&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;#membership&quot;&gt;Membership&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;#delegation&quot;&gt;Delegation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bundling&quot;&gt;Bundling&lt;&#x2F;h3&gt;
&lt;p&gt;One of the most frequent uses of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; is to disseminate the multimedia content that is tied to the tokens. In the event that someone wants to offer a bundle of NFTs from various collections, there is currently no easy way of bundling all of these together and handle their sale as a single transaction. This proposal introduces a standardized way of doing so. Nesting all of the tokens into a simple bundle and selling that bundle would transfer the control of all of the tokens to the buyer in a single transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collecting&quot;&gt;Collecting&lt;&#x2F;h3&gt;
&lt;p&gt;A lot of NFT consumers collect them based on countless criteria. Some aim for utility of the tokens, some for the uniqueness, some for the visual appeal, etc. There is no standardized way to group the NFTs tied to a specific account. By nesting NFTs based on their owner&#x27;s preference, this proposal introduces the ability to do it. The root parent token could represent a certain group of tokens and all of the children nested into it would belong to it.&lt;&#x2F;p&gt;
&lt;p&gt;The rise of soulbound, non-transferable, tokens, introduces another need for this proposal. Having a token with multiple soulbound traits (child tokens), allows for numerous use cases. One concrete example of this can be drawn from supply chains use case. A shipping container, represented by an NFT with its own traits, could have multiple child tokens denoting each leg of its journey.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;membership&quot;&gt;Membership&lt;&#x2F;h3&gt;
&lt;p&gt;A common utility attached to NFTs is a membership to a Decentralised Autonomous Organization (DAO) or to some other closed-access group. Some of these organizations and groups occasionally mint NFTs to the current holders of the membership NFTs. With the ability to nest mint a token into a token, such minting could be simplified, by simply minting the bonus NFT directly into the membership one.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delegation&quot;&gt;Delegation&lt;&#x2F;h3&gt;
&lt;p&gt;One of the core features of DAOs is voting and there are various approaches to it. One such mechanic is using fungible voting tokens where members can delegate their votes by sending these tokens to another member. Using this proposal, delegated voting could be handled by nesting your voting NFT into the one you are delegating your votes to and transferring it when the member no longer wishes to delegate their votes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-6059 Parent-Governed Nestable Non-Fungible Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-6059&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x42b0e56f.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC6059&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The core struct of ownership.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `DirectOwner` struct is used to store information of the next immediate owner, be it the parent token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * an `ERC721Receiver` contract or an externally owned account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the token is not owned by an NFT, the `tokenId` MUST equal `0`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ownerAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the owner of the token. If the owner is another token, then the address MUST be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  the one of the parent token&amp;#39;s collection smart contract. If the owner is externally owned account, the address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST be the address of this account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DirectOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; ownerAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that the token is being transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `tokenId` token is transferred from `from` to `to`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the previous immediate owner, which is a smart contract if the token was nested.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the new immediate owner, which is a smart contract if the token is being nested.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the previous parent token. If the token was not nested before, the value MUST be `0`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; toTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the new parent token. If the token is not being nested, the value MUST be `0`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NestTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a new token has been added to a given token&amp;#39;s pending children array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a child NFT is added to a token&amp;#39;s pending array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that received a new pending child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the proposed child token in the parent token&amp;#39;s pending children array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the proposed child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildProposed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that a new child token was accepted by the parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a parent token accepts a token from its pending array, migrating it to the active array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that accepted a new child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the newly accepted child token in the parent token&amp;#39;s active children array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildAccepted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that all pending child tokens of a given token have been rejected.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token removes all a child tokens from its pending array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that rejected all of the pending children&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AllChildrenRejected&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners a child token has been transferred from parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a token transfers a child from itself, transferring ownership.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that transferred a child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of a child in the array from which it is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fromPending&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean value signifying whether the token was in the pending child tokens array (`true`) or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  in the active child tokens array (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ChildTransferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromPending&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The core child token struct, holding the information about the child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contractAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Child&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; contractAddress&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the *root* owner of a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The *root* owner of the token is the top-level owner in the hierarchy which is not an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the token is owned by another NFT, it MUST recursively look up the parent&amp;#39;s root owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which the *root* owner has been retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The *root* owner of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the immediate owner of the given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If the immediate owner is another token, the address returned, MUST be the one of the parent token&amp;#39;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  collection smart contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which the direct owner is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the given token&amp;#39;s owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ID of the parent token. MUST be `0` if the owner is not an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean value signifying whether the owner is an NFT or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; directOwnerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        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 class=&quot;z-support&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 class=&quot;z-support&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 class=&quot;z-support&quot;&gt;            bool&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to burn a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When a token is burned, all of its child tokens are recursively burned as well.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When specifying the maximum recursive burns, the execution MUST be reverted if there are more children to be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  burned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Setting the `maxRecursiveBurn` value to 0 SHOULD only attempt to burn the specified token and MUST revert if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  there are any child tokens present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; maxRecursiveBurns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maximum number of tokens to recursively burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of recursively burned children&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; maxRecursiveBurns&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to add a child token to a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This adds the child token into the given parent token&amp;#39;s pending child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The destination token MUST NOT be a child token of the token being transferred or one of its downstream&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method MUST NOT be called directly. It MUST only be called from an instance of `IERC6059` as part of a &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        `nestTransfer` or `transferChild` to an NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `directOwnerOf` on the child contract MUST resolve to the called contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - the pending array of the parent contract MUST not be full.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token to receive the new child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the new proposed child token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to accept a pending child token for a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This moves the child token from parent token&amp;#39;s pending child tokens array into the active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the child token is being accepted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token to accept in the pending children array of a given token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the collection smart contract of the child token expected to be at the specified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token expected to be located at the specified index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to reject all pending children of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Removes the children from the pending array mapping.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The children&amp;#39;s ownership structures are not updated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `parentId` MUST exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to reject all of the pending tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Maximum number of expected children to reject, used to prevent from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  rejecting children which arrive just before this operation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; rejectAllChildren&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to transfer a child token from a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST remove the child from the parent&amp;#39;s active or pending children.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When transferring a child token, the owner of the token MUST be set to `to`, or not updated in the event of `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  being the `0x0` address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token from which the child token is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to which to transfer the token to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to receive this child token (MUST be 0 if the destination is not a token)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of a token we are transferring, in the array it belongs to (can be either active array or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  pending array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the child token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the child token in its own collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean value indicating whether the child token being transferred is in the pending array of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  parent token (`true`) or in the active array (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, sent in call to `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the active child tokens of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns array of Child structs existing for parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to retrieve the active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of Child structs containing the parent token&amp;#39;s active child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childrenOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the pending child tokens of a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns array of pending Child structs existing for given parent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which to retrieve the pending child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of Child structs containing the parent token&amp;#39;s pending child tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pendingChildrenOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve a specific active child token for a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a single Child struct locating at `index` of parent token&amp;#39;s active child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the child is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token in the parent token&amp;#39;s active child tokens array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A Child struct containing data about the specified child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; childOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve a specific pending child token from a given parent token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns a single Child struct locating at `index` of parent token&amp;#39;s active child tokens array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The Child struct consists of the following values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      tokenId,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      contractAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the parent token for which the pending child token is being retrieved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the child token in the parent token&amp;#39;s pending child tokens array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A Child struct containing data about the specified child&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pendingChildOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parentId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Child&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to transfer the token into another token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The destination token MUST NOT be a child token of the token being transferred or one of its downstream&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  child tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the direct owner of the token to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the receiving token&amp;#39;s collection smart contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to receive the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nestTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ID MUST never be a &lt;code&gt;0&lt;&#x2F;code&gt; value, as this proposal uses &lt;code&gt;0&lt;&#x2F;code&gt; values do signify that the token&#x2F;destination is not an NFT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;How to name the proposal?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
In an effort to provide as much information about the proposal we identified the most important aspect of the proposal; the parent centered control over nesting. The child token&#x27;s role is only to be able to be &lt;code&gt;Nestable&lt;&#x2F;code&gt; and support a token owning it. This is how we landed on the &lt;code&gt;Parent-Centered&lt;&#x2F;code&gt; part of the title.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is automatically accepting a child using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; permit-style signatures not a part of this proposal?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
For consistency. This proposal extends ERC-721 which already uses 1 transaction for approving operations with tokens. It would be inconsistent to have this and also support signing messages for operations with assets.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why use indexes?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
To reduce the gas consumption. If the token ID was used to find which token to accept or reject, iteration over arrays would be required and the cost of the operation would depend on the size of the active or pending children arrays. With the index, the cost is fixed. Lists of active and pending children per token need to be maintained, since methods to get them are part of the proposed interface.&lt;br &#x2F;&gt;
To avoid race conditions in which the index of a token changes, the expected token ID as well as the expected token&#x27;s collection smart contract is included in operations requiring token index, to verify that the token being accessed using the index is the expected one.&lt;br &#x2F;&gt;
Implementation that would internally keep track of indices using mapping was attempted. The minimum cost of accepting a child token was increased by over 20% and the cost of minting has increased by over 15%. We concluded that it is not necessary for this proposal and can be implemented as an extension for use cases willing to accept the increased transaction cost this incurs. In the sample implementation provided, there are several hooks which make this possible.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is the pending children array limited instead of supporting pagination?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The pending child tokens array is not meant to be a buffer to collect the tokens that the root owner of the parent token wants to keep, but not enough to promote them to active children. It is meant to be an easily traversable list of child token candidates and should be regularly maintained; by either accepting or rejecting proposed child tokens. There is also no need for the pending child tokens array to be unbounded, because active child tokens array is.&lt;br &#x2F;&gt;
Another benefit of having bounded child tokens array is to guard against spam and griefing. As minting malicious or spam tokens could be relatively easy and low-cost, the bounded pending array assures that all of the tokens in it are easy to identify and that legitimate tokens are not lost in a flood of spam tokens, if one occurs.&lt;br &#x2F;&gt;
A consideration tied to this issue was also how to make sure, that a legitimate token is not accidentally rejected when clearing the pending child tokens array. We added the maximum pending children to reject argument to the clear pending child tokens array call. This assures that only the intended number of pending child tokens is rejected and if a new token is added to the pending child tokens array during the course of preparing such call and executing it, the clearing of this array SHOULD result in a reverted transaction.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Should we allow tokens to be nested into one of its children?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The proposal enforces that a parent token can&#x27;t be nested into one of its child token, or downstream child tokens for that matter. A parent token and its children are all managed by the parent token&#x27;s root owner. This means that if a token would be nested into one of its children, this would create the ownership loop and none of the tokens within the loop could be managed anymore.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is there not a &quot;safe&quot; nest transfer method?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;code&gt;nestTransfer&lt;&#x2F;code&gt; is always &quot;safe&quot; since it MUST check for &lt;code&gt;IERC6059&lt;&#x2F;code&gt; compatibility on the destination.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How does this proposal differ from the other proposals trying to address a similar problem?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
This interface allows for tokens to both be sent to and receive other tokens. The propose-accept and parent governed patterns allow for a more secure use. The backward compatibility is only added for ERC-721, allowing for a simpler interface. The proposal also allows for different collections to inter-operate, meaning that nesting is not locked to a single smart contract, but can be executed between completely separate NFT collections.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;propose-commit-pattern-for-child-token-management&quot;&gt;Propose-Commit pattern for child token management&lt;&#x2F;h3&gt;
&lt;p&gt;Adding child tokens to a parent token MUST be done in the form of propose-commit pattern to allow for limited mutability by a 3rd party. When adding a child token to a parent token, it is first placed in a &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; array, and MUST be migrated to the &lt;em&gt;&quot;Active&quot;&lt;&#x2F;em&gt; array by the parent token&#x27;s root owner. The &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; child tokens array SHOULD be limited to 128 slots to prevent spam and griefing.&lt;&#x2F;p&gt;
&lt;p&gt;The limitation that only the root owner can accept the child tokens also introduces a trust inherent to the proposal. This ensures that the root owner of the token has full control over the token. No one can force the user to accept a child if they don&#x27;t want to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parent-governed-pattern&quot;&gt;Parent Governed pattern&lt;&#x2F;h3&gt;
&lt;p&gt;The parent NFT of a nested token and the parent&#x27;s root owner are in all aspects the true owners of it. Once you send a token to another one you give up ownership.&lt;&#x2F;p&gt;
&lt;p&gt;We continue to use ERC-721&#x27;s &lt;code&gt;ownerOf&lt;&#x2F;code&gt; functionality which will now recursively look up through parents until it finds an address which is not an NFT, this is referred to as the &lt;em&gt;root owner&lt;&#x2F;em&gt;. Additionally we provide the &lt;code&gt;directOwnerOf&lt;&#x2F;code&gt; which returns the most immediate owner of a token using 3 values: the owner address, the tokenId which MUST be 0 if the direct owner is not an NFT, and a flag indicating whether or not the parent is an NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The root owner or an approved party MUST be able do the following operations on children: &lt;code&gt;acceptChild&lt;&#x2F;code&gt;, &lt;code&gt;rejectAllChildren&lt;&#x2F;code&gt; and &lt;code&gt;transferChild&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The root owner or an approved party MUST also be allowed to do these operations only when token is not owned by an NFT: &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;, &lt;code&gt;nestTransferFrom&lt;&#x2F;code&gt;, &lt;code&gt;burn&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the token is owned by an NFT, only the parent NFT itself MUST be allowed to execute the operations listed above. Transfers MUST be done from the parent token, using &lt;code&gt;transferChild&lt;&#x2F;code&gt;, this method in turn SHOULD call &lt;code&gt;nestTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; in the child token&#x27;s smart contract, according to whether the destination is an NFT or not. For burning, tokens must first be transferred to an EOA and then burned.&lt;&#x2F;p&gt;
&lt;p&gt;We add this restriction to prevent inconsistencies on parent contracts, since only the &lt;code&gt;transferChild&lt;&#x2F;code&gt; method takes care of removing the child from the parent when it is being transferred out of it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;child-token-management&quot;&gt;Child token management&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal introduces a number of child token management functions. In addition to the permissioned migration from &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; to &lt;em&gt;&quot;Active&quot;&lt;&#x2F;em&gt; child tokens array, the main token management function from this proposal is the &lt;code&gt;tranferChild&lt;&#x2F;code&gt; function. The following state transitions of a child token are available with it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reject child token&lt;&#x2F;li&gt;
&lt;li&gt;Abandon child token&lt;&#x2F;li&gt;
&lt;li&gt;Unnest child token&lt;&#x2F;li&gt;
&lt;li&gt;Transfer the child token to an EOA or an &lt;code&gt;ERC721Receiver&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Transfer the child token into a new parent token&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To better understand how these state transitions are achieved, we have to look at the available parameters passed to &lt;code&gt;transferChild&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferChild&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; destinationId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; childId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isPending&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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 class=&quot;z-storage z-type&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;Based on the desired state transitions, the values of these parameters have to be set accordingly (any parameters not set in the following examples depend on the child token being managed):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reject child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-reject-child.png&quot; alt=&quot;Reject child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Abandon child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-abandon-child.png&quot; alt=&quot;Abandon child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Unnest child token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-unnest-child.png&quot; alt=&quot;Unnest child token&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transfer the child token to an EOA or an &lt;code&gt;ERC721Receiver&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-transfer-child-to-eoa.png&quot; alt=&quot;Transfer child token to EOA&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transfer the child token into a new parent token&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;img&#x2F;eip-6059-transfer-child-to-token.png&quot; alt=&quot;Transfer child token to parent token&quot; &#x2F;&gt;&lt;br &#x2F;&gt;
This state change places the token in the pending array of the new parent token. The child token still needs to be accepted by the new parent token&#x27;s root owner in order to be placed into the active array of that token.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Nestable token standard has been made compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; in order to take advantage of the robust tooling available for implementations of ERC-721 and to ensure compatibility with existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;test&#x2F;nestable.ts&quot;&gt;&lt;code&gt;nestable.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-6059&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6059&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;NestableToken.sol&quot;&gt;&lt;code&gt;NestableToken.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; apply: hidden logic may be present in any of the functions, including burn, add child, accept child, and more.&lt;&#x2F;p&gt;
&lt;p&gt;Since the current owner of the token is allowed to manage the token, there is a possibility that after the parent token is listed for sale, the seller might remove a child token just before before the sale and thus the buyer would not receive the expected child token. This is a risk that is inherent to the design of this standard. Marketplaces should take this into account and provide a way to verify the expected child tokens are present when the parent token is being sold or to guard against such a malicious behaviour in another way.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>eth&#x2F;68 - Add tx type to tx announcement</title>
        <published>2022-10-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5793/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5793-eth-68-add-transaction-type-to-tx-announcement/11364" />
        

        <id>https://wg-eips.ritovision.com/5793/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        

        
        <category
            term="tag:eip:5793"
            label="EIP-5793" />
        

        
        

        
        <summary type="html">Adds the transaction type and transaction size to tx announcement messages in the wire protocol</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5793/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Ethereum Wire Protocol defines request and response messages for exchanging data between clients. The &lt;code&gt;NewPooledTransactionHashes&lt;&#x2F;code&gt; message announces transactions available in the node. This EIP extends this announcement message such that beside the transaction hashes, the node sends the transaction types and their sizes (as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt;) as well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;NewPooledTransactionHashes&lt;&#x2F;code&gt; message announces transaction hashes, allowing the peer to selectively fetch transactions it does not yet have.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;&quot;&gt;EIP-4844&lt;&#x2F;a&gt; introduces a new transaction type for blob transactions. Since these blob transactions are large, naively broadcasting them to &lt;code&gt;sqrt(peers)&lt;&#x2F;code&gt; could significantly increase bandwidth requirements. Adding the transaction type and the size to the announcement message will allow nodes to select which transactions they want to fetch and also allow them to load balance or throttle peers based on past behavior.&lt;&#x2F;p&gt;
&lt;p&gt;The added metadata fields will also enable future - upgradeless - protocol tweaks to prevent certain transaction type (e.g. blob transactions) or certain transaction sizes (e.g. 128KB+) from being blindly broadcast to many peers. Enforcing announcements only and retrieval on demand would ensure a much more predictable networking behavior, limiting the amplification effect of transaction propagation DoS attack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Modify the &lt;code&gt;NewPooledTransactionHashes (0x08)&lt;&#x2F;code&gt; message:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;(eth&#x2F;67)&lt;&#x2F;strong&gt;: &lt;code&gt;[hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;(eth&#x2F;68)&lt;&#x2F;strong&gt;: &lt;code&gt;[types: B, [size_0: P, size_1: P, ...], [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The new &lt;code&gt;types&lt;&#x2F;code&gt; element refers to the transaction types of the announced hashes. Note the
transaction types are packed as a &#x27;byte array&#x27; instead of a list.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;size_0&lt;&#x2F;code&gt;, &lt;code&gt;size_1&lt;&#x2F;code&gt; etc. elements refer to the transaction sizes of the announced hashes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This change will make the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol future-proof for new transaction types that might not be relevant for all nodes. It gives the receiving node better control over the data it fetches from the peer as well as allow throttling the download of specific types.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;types&lt;&#x2F;code&gt; message element is a byte array because early implementations of this EIP
erroneously implemented it that way. It was later decided to keep this behavior in order
to minimize work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP changes the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol and requires rolling out a new version, &lt;code&gt;eth&#x2F;68&lt;&#x2F;code&gt;. Supporting multiple versions of a wire protocol is possible. Rolling out a new version does not break older clients immediately, since they can keep using protocol version &lt;code&gt;eth&#x2F;67&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change consensus rules of the EVM and does not require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Wallet Call API</title>
        <published>2022-10-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Moody Salem</name><uri>https://github.com/moodysalem</uri>
	</author>
	
	<author>
		<name>Lukas Rosario</name><uri>https://github.com/lukasrosario</uri>
	</author>
	
	<author>
		<name>Wilson Cusack</name><uri>https://github.com/wilsoncusack</uri>
	</author>
	
	<author>
		<name>Dror Tirosh</name><uri>https://github.com/drortirosh</uri>
	</author>
	
	<author>
		<name>Jake Moxey</name><uri>https://github.com/jxom</uri>
	</author>
	
	<author>
		<name>Derek Rein</name><uri>https://github.com/arein</uri>
	</author>
	
	<author>
		<name>Alex Forshtat</name><uri>https://github.com/forshtat</uri>
	</author>
	
	<author>
		<name>Sam Wilson</name><uri>https://github.com/SamWilsn</uri><email>sam@binarycake.ca</email>
	</author>
	
	<author>
		<name>Borislav Itskov</name><uri>https://github.com/Oxbobby</uri>
	</author>
	
	<author>
		<name>Joao Tavares</name><uri>https://github.com/cryptotavares</uri>
	</author>
	
	<author>
		<name>Adam Fuller</name><uri>https://github.com/azf20</uri>
	</author>
	
	<author>
		<name>Philip Liao</name><uri>https://github.com/phil-ociraptor</uri>
	</author>
	
	<author>
		<name>bumblefudge</name><uri>https://github.com/bumblefudge</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5792/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5792-wallet-abstract-transaction-send-api/11374" />
        

        <id>https://wg-eips.ritovision.com/5792/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5792"
            label="EIP-5792" />
        

        
        

        
        <summary type="html">Adds JSON-RPC methods for sending multiple calls from the user&#x27;s wallet, and checking their status</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5792/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Defines new JSON-RPC methods which enable apps to ask a wallet to process a batch of onchain write calls and to check on the status of those calls.
Applications can specify that these onchain calls be executed taking advantage of specific capabilities previously expressed by the wallet; an additional, novel wallet RPC is defined to enable apps to query the wallet for those capabilities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The current methods used to send transactions from the user wallet and check their status are &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; and &lt;code&gt;eth_getTransactionReceipt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The current methods used to send transactions from the user wallet and check their status do not meet modern developer demands and cannot accommodate new transaction formats. Even the name–- &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt;-– is an artifact of a time when nodes served as wallets.&lt;&#x2F;p&gt;
&lt;p&gt;Today, developers want to send multiple calls batched together in a single RPC call, which many smart accounts can, in turn, execute atomically in a single transaction. Developers also want to make use of features afforded by new transaction formats, like paymasters in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; transactions. &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; offers no way to do these things.&lt;&#x2F;p&gt;
&lt;p&gt;In updating to a new set of &lt;code&gt;wallet_&lt;&#x2F;code&gt; RPCs, our main goals are to enforce a clean separation of wallet and app concerns, enable developers to make use of things like paymasters and batch transactions, and to create a clear way for more safely discoverable features to be added over time with minimal coordination.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Four new JSON-RPC methods are added: three are for handling batches of onchain calls, and one is for querying support for wallet capabilities, such as to make better use of the three batching methods.
Apps may begin using these first three methods immediately, falling back to &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; and &lt;code&gt;eth_getTransactionReceipt&lt;&#x2F;code&gt; when they are not available.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-sendcalls&quot;&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Requests that a wallet submits a batch of calls. &lt;code&gt;from&lt;&#x2F;code&gt; and &lt;code&gt;chainId&lt;&#x2F;code&gt; are identified by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; integers expressed in hexadecimal notation,
with &lt;code&gt;0x&lt;&#x2F;code&gt; prefix and no leading zeroes for the &lt;code&gt;chainId&lt;&#x2F;code&gt; value.
The items in the &lt;code&gt;calls&lt;&#x2F;code&gt; field are simple &lt;code&gt;{to, data, value}&lt;&#x2F;code&gt; tuples.&lt;&#x2F;p&gt;
&lt;p&gt;The capabilities field is how an app can communicate with a wallet about capabilities a wallet supports. For example, this is where an app can specify a paymaster service URL from which an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; wallet can request a &lt;code&gt;paymasterAndData&lt;&#x2F;code&gt; input for a user operation.&lt;&#x2F;p&gt;
&lt;p&gt;Each capability defined in the &quot;capabilities&quot; member can define global or call specific fields.
These fields are set inside this capability&#x27;s entry in the &lt;code&gt;capabilities&lt;&#x2F;code&gt; object.
Each entity in the &lt;code&gt;calls&lt;&#x2F;code&gt; field may contain an optional &lt;code&gt;capabilities&lt;&#x2F;code&gt; object.
This object allows the applications to attach a capability-specific metadata to individual calls.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;atomicRequired&lt;&#x2F;code&gt; field specifies if a wallet is required to handle the batch of calls atomically or not. The wallet capacity to execute batch calls atomically is exposed through the built in &lt;code&gt;atomic&lt;&#x2F;code&gt; capability and can be sourced via &lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt;..&lt;&#x2F;p&gt;
&lt;p&gt;Unless these requirements are explicitly overridden by a certain &lt;code&gt;capability&lt;&#x2F;code&gt;, the wallet must adhere to the following rules.
Note that such a &lt;code&gt;capability&lt;&#x2F;code&gt; is not in the scope of this EIP and should be defined in its own ERC.&lt;&#x2F;p&gt;
&lt;p&gt;The wallet:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MUST send the calls in the order specified in the request&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUST send the calls on the same chain identified by the request&#x27;s &lt;code&gt;chainId&lt;&#x2F;code&gt; property&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUST send the calls from the address specified in the request&#x27;s &lt;code&gt;from&lt;&#x2F;code&gt; property, if provided&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;from&lt;&#x2F;code&gt; is not provided the wallet SHOULD present the user with an opportunity to view and select the &lt;code&gt;from&lt;&#x2F;code&gt; address during confirmation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUST NOT await for any calls to be finalized to complete the batch&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUST NOT send any calls from the request if the user rejects the request&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;code&gt;atomicRequired&lt;&#x2F;code&gt; is set to &lt;code&gt;true&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST execute all calls atomically, meaning that either all calls execute successfully or no material effects appear on chain.&lt;&#x2F;li&gt;
&lt;li&gt;MUST execute all calls contiguously, meaning no other transactions&#x2F;calls may be interleaved with the calls from this batch.&lt;&#x2F;li&gt;
&lt;li&gt;If a wallet is able to upgrade its atomicity guarantees from &lt;code&gt;ready&lt;&#x2F;code&gt; to &lt;code&gt;supported&lt;&#x2F;code&gt; but has not yet done so, it MUST upgrade before proceeding to submit the calls with the above guarantees.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;code&gt;atomicRequired&lt;&#x2F;code&gt; is set to &lt;code&gt;false&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MAY execute all calls sequentially without any atomicity&#x2F;contiguity guarantees.&lt;&#x2F;li&gt;
&lt;li&gt;If a wallet is capable of providing atomicity guarantees, it MAY execute the batch atomically.&lt;&#x2F;li&gt;
&lt;li&gt;If a wallet is able to upgrade its atomicity guarantees to &lt;code&gt;supported&lt;&#x2F;code&gt; (see &lt;code&gt;atomic&lt;&#x2F;code&gt; capability definition below), it MAY do so and then execute the batch atomically.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MAY reject the request if the from address does not match the enabled account&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MAY reject the request if one or more calls in the batch is expected to fail, when simulated sequentially&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUST reject the request if it contains a &lt;code&gt;capability&lt;&#x2F;code&gt; (either top-level or call-level) that is not supported by the wallet and the &lt;code&gt;capability&lt;&#x2F;code&gt; is not explicitly marked as optional.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Applications may mark a capability as optional by setting &lt;code&gt;optional&lt;&#x2F;code&gt; to &lt;code&gt;true&lt;&#x2F;code&gt;. See the RPC Specification section below for details.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If provided, the wallet MUST respect the &lt;code&gt;id&lt;&#x2F;code&gt; field and return it in the response.&lt;&#x2F;p&gt;
&lt;p&gt;Identifiers, whether provided by the app or generated by the wallet, MUST be a unique string up to 4096 bytes (8194 characters including leading &lt;code&gt;0x&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;App-provided &lt;code&gt;id&lt;&#x2F;code&gt;s MUST be unique per sender per app, where each &quot;app&quot; SHOULD be identified by their domain.&lt;&#x2F;p&gt;
&lt;p&gt;Wallets MUST reject requests with duplicate &lt;code&gt;id&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;p&gt;Within 24 hours from the corresponding &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;, wallets SHOULD return a call-batch status when &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; is called with the same &lt;code&gt;id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;capabilities&lt;&#x2F;code&gt; response object allows the wallets to attach a capability-specific metadata to the response.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-sendcalls-rpc-specification&quot;&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; RPC Specification&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Capability&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;  [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  optional&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SendCallsParams&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;  version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;  chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hex chain id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  atomicRequired&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  calls&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;    to&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;    data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;    value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hex value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    capabilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Capability&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;  capabilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Capability&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SendCallsResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;  id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  capabilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;wallet-sendcalls-example-parameters&quot;&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; Example Parameters&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&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&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;from&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd46e8dd67c5d32be8058bb8eb970870f07244567&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;atomicRequired&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;calls&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd46e8dd67c5d32be8058bb8eb970870f07244567&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x9184e72a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd46e8dd67c5d32be8058bb8eb970870f07244567&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x182183&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xfbadbaf01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;capabilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;paymasterService&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;optional&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&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;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;Note that since the &lt;code&gt;paymasterService&lt;&#x2F;code&gt; &lt;code&gt;capability&lt;&#x2F;code&gt; is marked as optional, wallets that do not support it will still process and handle the request as if the capability had not been present. If this &lt;code&gt;optional&lt;&#x2F;code&gt; field were set to &lt;code&gt;false&lt;&#x2F;code&gt; or absent from the request, wallets that do not support the &lt;code&gt;capability&lt;&#x2F;code&gt; MUST reject the request.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;wallet-sendcalls-example-return-value&quot;&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; Example Return Value&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;wallet-getcallsstatus&quot;&gt;&lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Returns the status of a call batch that was sent via &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;.
The identifier of the batch is the value returned from the &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; RPC.
Note that the &lt;code&gt;receipts&lt;&#x2F;code&gt; objects of this method&#x27;s response is a strict subset of the object returned by &lt;code&gt;eth_getTransactionReceipt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;capabilities&lt;&#x2F;code&gt; object allows the wallets to attach a capability-specific metadata to the response.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;atomic&lt;&#x2F;code&gt; field specifies how the wallet handled the batch of calls, which influences the structure of the &lt;code&gt;receipts&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The receipts in the &lt;code&gt;receipts&lt;&#x2F;code&gt; field MUST be in the order that they are included onchain.&lt;&#x2F;li&gt;
&lt;li&gt;If a wallet executes multiple calls &lt;strong&gt;atomically&lt;&#x2F;strong&gt;, &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; MAY return an object with a &lt;code&gt;receipts&lt;&#x2F;code&gt; field that contains a single transaction receipt or an array of receipts, corresponding to how the batch of transactions were included onchain. It also MUST be explicit and return an &lt;code&gt;atomic&lt;&#x2F;code&gt; field set to &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If a wallet executes multiple calls &lt;strong&gt;non-atomically&lt;&#x2F;strong&gt;, &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; MUST return an object with a &lt;code&gt;receipts&lt;&#x2F;code&gt; field that contains &lt;strong&gt;an array of receipts&lt;&#x2F;strong&gt; for all transactions containing batch calls that were included onchain. This includes the batch calls that were included on-chain but eventually reverted. It also MUST be explicit and return a &lt;code&gt;atomic&lt;&#x2F;code&gt; field set to &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;logs&lt;&#x2F;code&gt; in the receipt objects MUST only include logs relevant to the calls submitted using &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;. For example, in the case of a transaction submitted onchain by an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; bundler, the logs must only include those relevant to the user operation constructed using the calls submitted via &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;. I.e. the logs should not include those from other unrelated user operations submitted in the same bundle.
&lt;ul&gt;
&lt;li&gt;Similarly, if a user upgrades their wallet to support atomicity before submitting a batch of calls from an app, the logs MUST NOT include those emitted as part of the upgrade process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;wallet-getcallsstatus-rpc-specification&quot;&gt;&lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; RPC Specification&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GetCallsParams&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GetCallsResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;  version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;  chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;  status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See &amp;quot;Status Codes&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  atomic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  receipts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;    logs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;      address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;      data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;      topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;    status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hex 1 or 0 for success or failure, respectively&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    blockHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;    blockNumber&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;    gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-variable&quot;&gt;    transactionHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;  capabilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&gt;&lt;span&gt;&amp;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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;status-codes-for-status-field&quot;&gt;Status Codes for &lt;code&gt;status&lt;&#x2F;code&gt; field&lt;&#x2F;h5&gt;
&lt;p&gt;The purpose of the &lt;code&gt;status&lt;&#x2F;code&gt; field is to provide a short summary of the current status of the batch.
It provides some off-chain context to the array of inner transaction &lt;code&gt;receipts&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Status codes follow these categories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1xx: Pending states&lt;&#x2F;li&gt;
&lt;li&gt;2xx: Confirmed states&lt;&#x2F;li&gt;
&lt;li&gt;4xx: Offchain failures&lt;&#x2F;li&gt;
&lt;li&gt;5xx: Chain rules failures&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;td&gt;Batch has been received by the wallet but has not completed execution onchain (pending)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;td&gt;Batch has been included onchain without reverts, receipts array contains info of all calls (confirmed)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;400&lt;&#x2F;td&gt;&lt;td&gt;Batch has not been included onchain and wallet will not retry (offchain failure)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;500&lt;&#x2F;td&gt;&lt;td&gt;Batch reverted &lt;strong&gt;completely&lt;&#x2F;strong&gt; and only changes related to gas charge may have been included onchain (chain rules failure)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;600&lt;&#x2F;td&gt;&lt;td&gt;Batch reverted &lt;strong&gt;partially&lt;&#x2F;strong&gt; and some changes related to batch calls may have been included onchain (partial chain rules failure)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;More specific status codes within these categories should be proposed and agreed upon in separate ERCs.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;wallet-getcallsstatus-example-parameters&quot;&gt;&lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; Example Parameters&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;code&gt;id&lt;&#x2F;code&gt; batch identifier is a unique 64 bytes represented as a hex encoded string returned from &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;h5 id=&quot;wallet-getcallsstatus-example-return-value&quot;&gt;&lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; Example Return Value&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;atomic&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;receipts&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xa922b54716264130634d6ff183747a8ead91a40b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x5a2a90727cc9d000dd060b1132a5c977c9702bb3a52afe360c9c22f0e9451a68&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xabcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blockHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf19bbafd9fd0124ec110b848e8de4ab4f62bf60c189524e54213285e7f540d4a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blockNumber&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xabcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x9b7bb827c2e5e3c1a0a44dc53e573aa0b3af3bd1f9f5ed03071b100bb039eaff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h3 id=&quot;wallet-showcallsstatus&quot;&gt;&lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Requests that a wallet shows information about a given call bundle that was sent with &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;. Note that this method does not return anything for a known &lt;code&gt;id&lt;&#x2F;code&gt; batch identifier. If the identifier is not known, or in case of any other failure to execute &lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt; returns an RPC call error.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-showcallsstatus-rpc-specification&quot;&gt;&lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt; RPC Specification&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ShowCallsParams&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Call bundle identifier returned by wallet_sendCalls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;wallet-showcallsstatus-example-parameters&quot;&gt;&lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt; Example Parameters&lt;&#x2F;h5&gt;
&lt;p&gt;This method accepts a call bundle identifier returned by a &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;wallet-getcapabilities&quot;&gt;&lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This RPC allows an application to request capabilities from a wallet (e.g. batch transactions, paymaster communication), without distinct discovery and permission requests. For more on the difference between requesting capabilities and discovering features, see the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5792&#x2F;#privacy-considerations&quot;&gt;&quot;Privacy Considerations&quot; section&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This method SHOULD return an &lt;code&gt;4100 Unauthorized&lt;&#x2F;code&gt; error if the user has not already authorized a connection between the application and the requested address.&lt;&#x2F;p&gt;
&lt;p&gt;We expect the community to align on the definition of additional capabilities in separate ERCs over time.&lt;&#x2F;p&gt;
&lt;p&gt;Note that in addition to, or instead of, querying the wallet directly for capabilities, the same capability objects MAY be exposed out-of-band, such as in a &lt;code&gt;sessionProperties&lt;&#x2F;code&gt; and&#x2F;or &lt;code&gt;scopedProperties&lt;&#x2F;code&gt; collections persisted in a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ChainAgnostic&#x2F;CAIPs&#x2F;blob&#x2F;c599f7601d0ce83e6dd9f350c6c21d158d56fd6d&#x2F;CAIPs&#x2F;caip-25.md&quot;&gt;CAIP-25&lt;&#x2F;a&gt;-conformant wallet provider interface (see the ethereum usage profile for CAIP-25 for an example request and response), or in some other a well-known location (such as a URL derived from an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6963&#x2F;&quot;&gt;EIP-6963&lt;&#x2F;a&gt; &lt;code&gt;rdns&lt;&#x2F;code&gt; identifier).
Provider abstractions MAY also cache capabilities from previous requests or otherwise inject them from out-of-band to facilitate better user experience.
If any of these supplemental expressions of capabilities are contradicted by capabilities expressed in live wallet RPC responses, these latter values SHOULD be taken as the canonical and current expression of capabilities.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-getcapabilities-rpc-specification&quot;&gt;&lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt; RPC Specification&lt;&#x2F;h4&gt;
&lt;p&gt;Capabilities are returned in key&#x2F;value pairs, with the key naming a capability and a value conforming to a shape defined for that name, in an object keyed to the relevant &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; &lt;code&gt;chainId&lt;&#x2F;code&gt; expressed in hexadecimal notation.
Capabilities are nested in per-chain objects because wallets may support different capabilities across multiple chains authorized in a given session.
Capabilities that the wallet supports on all the chains SHOULD be included only once, using a special &lt;code&gt;chainID&lt;&#x2F;code&gt; value &lt;code&gt;&quot;0x0&quot;&lt;&#x2F;code&gt;, and SHOULD NOT be repeated in nested per-chain objects.
If a wallet does not support a chain that is requested in the &lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt; method, the wallet MUST NOT respond with an error, and MUST instead not include a key for the unsupported chain(s) in the response.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GetCapabilitiesParams&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Wallet address, array of queried chain ids (optional)&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 class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; GetCapabilitiesResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hex chain id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;wallet-getcapabilities-example-parameters&quot;&gt;&lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt; Example Parameters&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&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;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd46e8dd67c5d32be8058bb8eb970870f07244567&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x2105&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x14A34&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;wallet-getcapabilities-example-return-value&quot;&gt;&lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt; Example Return Value&lt;&#x2F;h5&gt;
&lt;p&gt;The capabilities below are for illustrative purposes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;flow-control&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;0x2105&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;paymasterService&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sessionKeys&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;0x14A34&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;auxiliaryFunds&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&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;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;h3 id=&quot;atomic-capability&quot;&gt;&lt;code&gt;atomic&lt;&#x2F;code&gt; Capability&lt;&#x2F;h3&gt;
&lt;p&gt;Like the illustrative examples given above and other capabilities to be defined in future EIPs, the &lt;code&gt;atomic&lt;&#x2F;code&gt; capability specifies how the wallet will execute the batches of transactions requested through &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;The valid JSON-RPC values for this &lt;code&gt;atomic&lt;&#x2F;code&gt; capability&#x27;s only property, &lt;code&gt;status&lt;&#x2F;code&gt;, are &lt;code&gt;supported&lt;&#x2F;code&gt;, &lt;code&gt;ready&lt;&#x2F;code&gt;, and &lt;code&gt;unsupported&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;supported&lt;&#x2F;code&gt; means that the wallet will execute the calls atomically and contiguously.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ready&lt;&#x2F;code&gt; means that the wallet is able to upgrade to &lt;code&gt;supported&lt;&#x2F;code&gt; pending user approval.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;unsupported&lt;&#x2F;code&gt; means that the wallet does not provide any atomicity or contiguity guarantees, nor will it suggest an upgrade to the user.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This capability is expressed separately on each chain and should be interpreted as a guarantee only for batches of transactions on that chain.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;atomic&lt;&#x2F;code&gt; capability is not present for a given chain, and unless it is explicitly overridden by another &lt;code&gt;capability&lt;&#x2F;code&gt; (not in scope of this EIP), it means that the wallet does not support batching for that given chain.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;atomic-capability-specification&quot;&gt;&lt;code&gt;atomic&lt;&#x2F;code&gt; Capability Specification&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AtomicCapability&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable&quot;&gt;  status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ready&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unsupported&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;wallet-getcapabilities-example-return-value-including-atomic&quot;&gt;&lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt; Example Return Value including &lt;code&gt;atomic&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;0x2105&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;atomic&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;0x14A34&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;atomic&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unsupported&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h3 id=&quot;error-codes&quot;&gt;Error Codes&lt;&#x2F;h3&gt;
&lt;p&gt;The following error codes are defined for the methods specified in this EIP. These errors follow the JSON-RPC 2.0 specification for error objects, which require a &lt;code&gt;code&lt;&#x2F;code&gt; and &lt;code&gt;message&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Message&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Related RPCs&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;-32602&lt;&#x2F;td&gt;&lt;td&gt;Invalid params&lt;&#x2F;td&gt;&lt;td&gt;The wallet cannot parse this request (e.g., missing 0x prefix, leading zeros in chain id, request fails schema validation)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;, &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt;, &lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt;, &lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4001&lt;&#x2F;td&gt;&lt;td&gt;User Rejected Request&lt;&#x2F;td&gt;&lt;td&gt;The user rejected submitting the batch of calls (from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4100&lt;&#x2F;td&gt;&lt;td&gt;Unauthorized&lt;&#x2F;td&gt;&lt;td&gt;The specified address is not connected or not in the wallet (from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;, &lt;code&gt;wallet_getCapabilities&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5700&lt;&#x2F;td&gt;&lt;td&gt;Unsupported non-optional capability&lt;&#x2F;td&gt;&lt;td&gt;This wallet does not support a capability that was not marked as optional&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5710&lt;&#x2F;td&gt;&lt;td&gt;Unsupported chain id&lt;&#x2F;td&gt;&lt;td&gt;This wallet does not support the specified chain id&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5720&lt;&#x2F;td&gt;&lt;td&gt;Duplicate ID&lt;&#x2F;td&gt;&lt;td&gt;There is already a bundle submitted with this id&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5730&lt;&#x2F;td&gt;&lt;td&gt;Unknown bundle id&lt;&#x2F;td&gt;&lt;td&gt;This bundle id is unknown &#x2F; has not been submitted&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt;, &lt;code&gt;wallet_showCallsStatus&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5740&lt;&#x2F;td&gt;&lt;td&gt;Bundle too large&lt;&#x2F;td&gt;&lt;td&gt;The call bundle is too large for the wallet to process&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5750&lt;&#x2F;td&gt;&lt;td&gt;Atomic-ready wallet rejected upgrade&lt;&#x2F;td&gt;&lt;td&gt;The wallet can support atomicity after an upgrade, but the user rejected the upgrade&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5760&lt;&#x2F;td&gt;&lt;td&gt;Atomicity not supported&lt;&#x2F;td&gt;&lt;td&gt;The wallet does not support atomic execution but the request requires it&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;on-naming&quot;&gt;On Naming&lt;&#x2F;h3&gt;
&lt;p&gt;We considered modifying &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; to add support for these new capabilities, but the method is ultimately an artifact of when nodes were used to sign transactions. We decided it is better to move forward with &lt;code&gt;wallet_&lt;&#x2F;code&gt;-namespaced methods that better describe what they are used for.&lt;&#x2F;p&gt;
&lt;p&gt;We also debated whether the methods should be called &lt;code&gt;wallet_sendTransaction&lt;&#x2F;code&gt;, &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt;, or something else. We ultimately landed on &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; because in the case of EOA wallets the &lt;code&gt;wallet_send*&lt;&#x2F;code&gt; method might send more than one transaction. Similarly, we decided against &lt;code&gt;wallet_sendTransactions&lt;&#x2F;code&gt; because in the case of other wallet implementations (e.g. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt;) multiple calls could result in a single transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;call-execution-atomicity&quot;&gt;Call Execution Atomicity&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; method accepts an array of &lt;code&gt;calls&lt;&#x2F;code&gt;. However, this proposal does not require that these calls be executed as part of a single transaction. It enables EOA wallets to express their ability to execute calls as part of a single transaction or as part of multiple transactions. It also enables Apps to express their minimum atomicity requirements for how calls must be executed.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;atomic&lt;&#x2F;code&gt; special capability was made an integral part of this specification in order promote expressiveness and facilitate adoption (from both wallets and apps). And due to its importance to reduce ambiguity between the App and the Wallet, the capability is expressed as a top-level field in the &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; request (through the &lt;code&gt;atomicRequired&lt;&#x2F;code&gt; parameter) and the &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; response (through the &lt;code&gt;atomic&lt;&#x2F;code&gt; field).&lt;&#x2F;p&gt;
&lt;p&gt;We initially proposed that multiple calls must be executed atomically, but after some debate we ultimately decided this was too opinionated. Instead, we are including a specification for an &lt;code&gt;atomic&lt;&#x2F;code&gt; capability. This allows for EOA wallets to accept multiple calls and still gives developers the option to only submit batched calls if they are executed atomically.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;call-gas-limit&quot;&gt;Call Gas Limit&lt;&#x2F;h3&gt;
&lt;p&gt;Our initial proposal included an optional &lt;code&gt;gas&lt;&#x2F;code&gt; field for each call in the &lt;code&gt;calls&lt;&#x2F;code&gt; field accepted by the &lt;code&gt;walletSendCalls&lt;&#x2F;code&gt; method. However, we realized this could be misleading because in the case of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; wallets you cannot specify a gas limit per call, only a single gas limit for all calls in the user operation. We then proposed a single &lt;code&gt;gas&lt;&#x2F;code&gt; value that would apply to all of the calls. This works for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt; wallets, but not for EOA wallets. When we decided that EOA wallets should be able to handle multiple calls, the common &lt;code&gt;gas&lt;&#x2F;code&gt; field became untenable across use cases and we removed it altogether.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Wallets that do not support the methods defined here SHOULD return error responses when these new JSON-RPC methods are called. Apps MAY attempt to send the same batch of calls serially via &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; when a call to these methods fails for lack of wallet support, or they MAY indicate to the user that their wallet is not supported and the request was not processed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Regardless of the &lt;code&gt;atomic&lt;&#x2F;code&gt; value specified, App developers MUST NOT assume that all calls will be sent in a single transaction. An example could be an L2 resistant to reorgs that implements a sendBundle or similar functionality.&lt;&#x2F;p&gt;
&lt;p&gt;Wallets MUST ensure that batch identifiers returned by &lt;code&gt;wallet_sendCalls&lt;&#x2F;code&gt; are unpredictable to prevent malicious apps from inferring information about other users&#x27; transactions.&lt;&#x2F;p&gt;
&lt;p&gt;Wallets MUST NOT leak sensitive information in &lt;code&gt;wallet_getCallsStatus&lt;&#x2F;code&gt; &lt;code&gt;capabilities&lt;&#x2F;code&gt; responses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;privacy-considerations&quot;&gt;Privacy Considerations&lt;&#x2F;h3&gt;
&lt;p&gt;Progressive authorization and progressive consent paradigms are important to modern user experience, as well as to preserving the anonymity of user agents. To protect these patterns from the cross-incentives of feature-discovery that enables better user experiences, capability semantics are used and the difference between lack of feature support and lack of feature permission explicitly occluded in the design of the &lt;code&gt;wallet_&lt;&#x2F;code&gt; RPC for querying capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, wallets are recommended to avoid exposing capabilities to untrusted callers or to more callers than necessary, as this may allow their &quot;user-agent&quot; (i.e. client software) to be &quot;fingerprinted&quot; or probabilistically identified, which combined with other deanonymization vectors inherent to the web platform could contribute to the deanonymization of the individual user or to the deanonymization of all users of a given client in aggregate. Similarly, applications over-querying capabilities or incentivizing capability oversharing (including third-party capability oversharing) is an anti-pattern to be avoided in the implementation of capability exchanges serving to discover features.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Context-Dependent Multi-Asset Tokens</title>
        <published>2022-10-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Bruno Škvorc</name><uri>https://github.com/Swader</uri>
	</author>
	
	<author>
		<name>Cicada</name><uri>https://github.com/CicadaNCR</uri>
	</author>
	
	<author>
		<name>Steven Pineda</name><uri>https://github.com/steven2308</uri>
	</author>
	
	<author>
		<name>Stevan Bogosavljevic</name><uri>https://github.com/stevyhacker</uri>
	</author>
	
	<author>
		<name>Jan Turk</name><uri>https://github.com/ThunderDeliverer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5773/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/multiresource-tokens/11326" />
        

        <id>https://wg-eips.ritovision.com/5773/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5773"
            label="ERC-5773" />
        

        
        

        
        <summary type="html">An interface for Multi-Asset tokens with context dependent asset type output controlled by owner&#x27;s preference.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5773/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The Multi-Asset NFT standard allows for the construction of a new primitive: context-dependent output of information per single NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The context-dependent output of information means that the asset in an appropriate format is displayed based on how the token is being accessed. I.e. if the token is being opened in an e-book reader, the PDF asset is displayed, if the token is opened in the marketplace, the PNG or the SVG asset is displayed, if the token is accessed from within a game, the 3D model asset is accessed and if the token is accessed by the (Internet of Things) IoT hub, the asset providing the necessary addressing and specification information is accessed.&lt;&#x2F;p&gt;
&lt;p&gt;An NFT can have multiple assets (outputs), which can be any kind of file to be served to the consumer, and orders them by priority. They do not have to match in mimetype or tokenURI, nor do they depend on one another. Assets are not standalone entities, but should be thought of as “namespaced tokenURIs” that can be ordered at will by the NFT owner, but only modified, updated, added, or removed if agreed on by both the owner of the token and the issuer of the token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having multiple assets associated with a single NFT allows for greater utility, usability and forward compatibility.&lt;&#x2F;p&gt;
&lt;p&gt;In the four years since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; was published, the need for additional functionality has resulted in countless extensions. This EIP improves upon ERC-721 in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;#cross-metaverse-compatibility&quot;&gt;Cross-metaverse compatibility&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;#multi-media-output&quot;&gt;Multi-media output&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;#media-redundancy&quot;&gt;Media redundancy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;#nft-evolution&quot;&gt;NFT evolution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;cross-metaverse-compatibility&quot;&gt;Cross-metaverse compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;At the time of writing this proposal, the metaverse is still a fledgling, not full defined, term. No matter how the definition of metaverse evolves, the proposal can support any number of different implementations.&lt;&#x2F;p&gt;
&lt;p&gt;Cross-metaverse compatibility could also be referred to as cross-engine compatibility. An example of this is where a cosmetic item for game A is not available in game B because the frameworks are incompatible.&lt;&#x2F;p&gt;
&lt;p&gt;Such NFT can be given further utility by means of new additional assets: more games, more cosmetic items, appended to the same NFT. Thus, a game cosmetic item as an NFT becomes an ever-evolving NFT of infinite utility.&lt;&#x2F;p&gt;
&lt;p&gt;The following is a more concrete example. One asset is a cosmetic item for game A, a file containing the cosmetic assets. Another is a cosmetic asset file for game B. A third is a generic asset intended to be shown in catalogs, marketplaces, portfolio trackers, or other generalized NFT viewers, containing a representation, stylized thumbnail, and animated demo&#x2F;trailer of the cosmetic item.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP adds a layer of abstraction, allowing game developers to directly pull asset data from a user&#x27;s NFTs instead of hard-coding it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multi-media-output&quot;&gt;Multi-media output&lt;&#x2F;h3&gt;
&lt;p&gt;An NFT of an eBook can be represented as a PDF, MP3, or some other format, depending on what software loads it. If loaded into an eBook reader, a PDF should be displayed, and if loaded into an audiobook application, the MP3 representation should be used. Other metadata could be present in the NFT (perhaps the book&#x27;s cover image) for identification on various marketplaces, Search Engine Result Pages (SERPs), or portfolio trackers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;media-redundancy&quot;&gt;Media redundancy&lt;&#x2F;h3&gt;
&lt;p&gt;Many NFTs are minted hastily without best practices in mind - specifically, many NFTs are minted with metadata centralized on a server somewhere or, in some cases, a hardcoded IPFS gateway which can also go down, instead of just an IPFS hash.&lt;&#x2F;p&gt;
&lt;p&gt;By adding the same metadata file as different assets, e.g., one asset of a metadata and its linked image on Arweave, one asset of this same combination on Sia, another of the same combination on IPFS, etc., the resilience of the metadata and its referenced information increases exponentially as the chances of all the protocols going down at once become less likely.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nft-evolution&quot;&gt;NFT evolution&lt;&#x2F;h3&gt;
&lt;p&gt;Many NFTs, particularly game related ones, require evolution. This is especially the case in modern metaverses where no metaverse is actually a metaverse - it is just a multiplayer game hosted on someone&#x27;s server which replaces username&#x2F;password logins with reading an account&#x27;s NFT balance.&lt;&#x2F;p&gt;
&lt;p&gt;When the server goes down or the game shuts down, the player ends up with nothing (loss of experience) or something unrelated (assets or accessories unrelated to the game experience, spamming the wallet, incompatible with other “verses” - see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;#cross-metaverse-compatibility&quot;&gt;cross-metaverse&lt;&#x2F;a&gt; compatibility above).&lt;&#x2F;p&gt;
&lt;p&gt;With Multi-Asset NFTs, a minter or another pre-approved entity is allowed to suggest a new asset to the NFT owner who can then accept it or reject it. The asset can even target an existing asset which is to be replaced.&lt;&#x2F;p&gt;
&lt;p&gt;Replacing an asset could, to some extent, be similar to replacing an ERC-721 token&#x27;s URI. When an asset is replaced a clear line of traceability remains; the old asset is still reachable and verifiable. Replacing an asset&#x27;s metadata URI obscures this lineage. It also gives more trust to the token owner if the issuer cannot replace the asset of the NFT at will. The propose-accept asset replacement mechanic of this proposal provides this assurance.&lt;&#x2F;p&gt;
&lt;p&gt;This allows level-up mechanics where, once enough experience has been collected, a user can accept the level-up. The level-up consists of a new asset being added to the NFT, and once accepted, this new asset replaces the old one.&lt;&#x2F;p&gt;
&lt;p&gt;As a concrete example, think of Pokemon™️ evolving - once enough experience has been attained, a trainer can choose to evolve their monster. With Multi-Asset NFTs, it is not necessary to have centralized control over metadata to replace it, nor is it necessary to airdrop another NFT into the user&#x27;s wallet - instead, a new Raichu asset is minted onto Pikachu, and if accepted, the Pikachu asset is gone, replaced by Raichu, which now has its own attributes, values, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Alternative example of this, could be version control of an IoT device&#x27;s firmware. An asset could represent its current firmware and once an update becomes available, the current asset could be replaced with the one containing the updated firmware.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-5773 Context-Dependent Multi-Asset Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-5773&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x06b4329a.&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5773&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that an asset object is initialised at `assetId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that was initialised&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AssetSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that an asset object at `assetId` is added to token&amp;#39;s pending asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of IDs of the tokens that received a new pending asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that has been added to the token&amp;#39;s pending assets array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; replacesId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that would be replaced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AssetAddedToTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; replacesId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that an asset object at `assetId` is accepted by the token and migrated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  from token&amp;#39;s pending assets array to active assets array of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that had a new asset accepted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that was accepted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; replacesId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that was replaced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AssetAccepted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; replacesId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that an asset object at `assetId` is rejected from token and is dropped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  from the pending assets array of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that had an asset rejected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset that was rejected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AssetRejected&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that token&amp;#39;s priority array is reordered.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that had the asset priority array updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AssetPrioritySet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that owner has granted an approval to the user to manage the assets of a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approvals must be cleared on transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that has granted the approval for all token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that has been granted approval to manage the token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token on which the approval was granted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to notify listeners that owner has granted approval to the user to manage assets of all of their&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that has granted the approval for all assets on all of their tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that has been granted the approval to manage the token&amp;#39;s assets on all of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Boolean value signifying whether the permission has been granted (`true`) or revoked (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAllForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Accepts an asset at from the pending array of given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Migrates the asset from the token&amp;#39;s pending asset array to the token&amp;#39;s active asset array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Active assets cannot be removed by anyone, but can be replaced by a new asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The caller must own the token or be approved to manage the token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `index` must be in range of the length of the pending asset array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits an {AssetAccepted} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which to accept the pending asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the asset in the pending array to accept&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Id of the asset expected to be in the index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; acceptAsset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rejects an asset from the pending array of given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Removes the asset from the token&amp;#39;s pending asset array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The caller must own the token or be approved to manage the token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `index` must be in range of the length of the pending asset array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits a {AssetRejected} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token that the asset is being rejected from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Index of the asset in the pending array to be rejected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Id of the asset expected to be in the index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; rejectAsset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rejects all assets from the pending array of a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Effectively deletes the pending array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The caller must own the token or be approved to manage the token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits a {AssetRejected} event with assetId = 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token of which to clear the pending array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to prevent from rejecting assets which arrive just before this operation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; rejectAllAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; maxRejections&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets a new priority array for a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The priority array is a non-sequential list of `uint16`s, where the lowest value is considered highest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  priority.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Value `0` of a priority is a special case equivalent to uninitialised.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The caller must own the token or be approved to manage the token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The length of `priorities` must be equal the length of the active assets array.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits a {AssetPrioritySet} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to set the priorities for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; priorities&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An array of priorities of active assets. The succession of items in the priorities array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  matches that of the succession of items in the active array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setPriority&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; priorities&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve IDs of the active assets of given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Asset data is stored by reference, in order to access the data corresponding to the ID, call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `getAssetMetadata(tokenId, assetId)`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; You can safely get 10k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to retrieve the IDs of the active assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of active asset IDs of the given token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getActiveAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve IDs of the pending assets of given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Asset data is stored by reference, in order to access the data corresponding to the ID, call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `getAssetMetadata(tokenId, assetId)`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to retrieve the IDs of the pending assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of pending asset IDs of the given token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getPendingAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the priorities of the active assets of a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Asset priorities are a non-sequential array of uint16 values with an array size equal to active asset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  priorites.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which to retrieve the priorities of the active assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;[] An array of priorities of the active assets of the given token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getActiveAssetPriorities&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the asset that will be replaced if a given asset from the token&amp;#39;s pending array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  is accepted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Asset data is stored by reference, in order to access the data corresponding to the ID, call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `getAssetMetadata(tokenId, assetId)`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token to check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newAssetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the pending asset which will be accepted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the asset which will be replaced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getAssetReplacements&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newAssetId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to fetch the asset metadata of the specified token&amp;#39;s active asset with the given index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Can be overridden to implement enumerate, fallback or other custom logic.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token from which to retrieve the asset metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Asset Id, must be in the active assets array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata of the asset belonging to the specified index in the token&amp;#39;s active assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getAssetMetadata&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to grant permission to the user to manage token&amp;#39;s assets.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This differs from transfer approvals, as approvals are not cleared when the approved party accepts or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  rejects an asset, or sets asset priorities. This approval is cleared on token transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only a single account can be approved at a time, so approving the `0x0` address clears previous approvals.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The caller must own the token or be an approved operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits an {ApprovalForAssets} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account to grant the approval to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which the approval to manage the assets is granted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approveForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to retrieve the address of the account approved to manage assets of a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ID of the token for which to retrieve the approved address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that is approved to manage the specified token&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApprovedForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to add or remove an operator of assets for the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Operators can call {acceptAsset}, {rejectAsset}, {rejectAllAssets} or {setPriority} for any token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  owned by the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  - The `operator` cannot be the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits an {ApprovalForAllForAssets} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account to which the operator role is granted or revoked from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean value indicating whether the operator role is being granted (`true`) or revoked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  (`false`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAllForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Used to check whether the address has been granted the operator role by a given address or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {setApprovalForAllForAssets}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that we are checking for whether it has granted the operator role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the account that we are checking whether it has the operator role or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The boolean value indicating whether the account we are checking has been granted the operator role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAllForAssets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;getAssetMetadata&lt;&#x2F;code&gt; function returns the asset&#x27;s metadata URI. The metadata, to which the metadata URI of the asset points, MAY contain a JSON response with the following fields:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The description of the token or asset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;mediaUri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ipfs:&#x2F;&#x2F;mediaOfTheAssetOrToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;thumbnailUri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ipfs:&#x2F;&#x2F;thumbnailOfTheAssetOrToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;externalUri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;uriToTheProjectWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;license&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;License name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;licenseUri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;uriToTheLicense&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;used&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;help&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;marketplaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;categorize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;the&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;asset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;or&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;preferThumb&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean flag indicating to UIs to prefer thumbnailUri instead of mediaUri wherever applicable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;label&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rarity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;epic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For backward compatibility&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;trait_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rarity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;label&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;red&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For backward compatibility&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;trait_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;label&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;height&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 192.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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For backward compatibility&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;trait_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;height&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;display_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;While this is the suggested JSON schema for the asset metadata, it is not enforced and MAY be structured completely differently based on implementer&#x27;s preference.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Designing the proposal, we considered the following questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Should we use Asset or Resource when referring to the structure that comprises the token?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
The original idea was to call the proposal Multi-Resource, but while this denoted the broadness of the structures that could be held by a single token, the term &lt;em&gt;asset&lt;&#x2F;em&gt; represents it better.&lt;br &#x2F;&gt;
An asset is defined as something that is owned by a person, company, or organization, such as money, property, or land. This is the best representation of what an asset of this proposal can be. An asset in this proposal can be a multimedia file, technical information, a land deed, or anything that the implementer has decided to be an asset of the token they are implementing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why are &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; permit-style signatures to manage approvals not used?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
For consistency. This proposal extends ERC-721 which already uses 1 transaction for approving operations with tokens. It would be inconsistent to have this and also support signing messages for operations with assets.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why use indexes?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
To reduce the gas consumption. If the asset ID was used to find which asset to accept or reject, iteration over arrays would be required and the cost of the operation would depend on the size of the active or pending assets arrays. With the index, the cost is fixed. A list of active and pending assets arrays per token need to be maintained, since methods to get them are part of the proposed interface.&lt;br &#x2F;&gt;
To avoid race conditions in which the index of an asset changes, the expected asset ID is included in operations requiring asset index, to verify that the asset being accessed using the index is the expected asset.&lt;br &#x2F;&gt;
Implementation that would internally keep track of indices using mapping was attempted. The average cost of adding an asset to a token increased by over 25%, costs of accepting and rejecting assets also increased 4.6% and 7.1% respectively. We concluded that it is not necessary for this proposal and can be implemented as an extension for use cases willing to accept this cost. In the sample implementation provided, there are several hooks which make this possible.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is a method to get all the assets not included?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Getting all assets might not be an operation necessary for all implementers. Additionally, it can be added either as an extension, doable with hooks, or can be emulated using an indexer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Why is pagination not included?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Asset IDs use &lt;code&gt;uint64&lt;&#x2F;code&gt;, testing has confirmed that the limit of IDs you can read before reaching the gas limit is around 30.000. This is not expected to be a common use case so it is not a part of the interface. However, an implementer can create an extension for this use case if needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How does this proposal differ from the other proposals trying to address a similar problem?&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
After reviewing them, we concluded that each contains at least one of these limitations:
&lt;ul&gt;
&lt;li&gt;Using a single URI which is replaced as new assets are needed, this introduces a trust issue for the token owner.&lt;&#x2F;li&gt;
&lt;li&gt;Focusing only on a type of asset, while this proposal is asset type agnostic.&lt;&#x2F;li&gt;
&lt;li&gt;Having a different token for each new use case, this means that the token is not forward-compatible.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;multi-asset-storage-schema&quot;&gt;Multi-Asset Storage Schema&lt;&#x2F;h3&gt;
&lt;p&gt;Assets are stored within a token as an array of &lt;code&gt;uint64&lt;&#x2F;code&gt; identifiers.&lt;&#x2F;p&gt;
&lt;p&gt;In order to reduce redundant on-chain string storage, multi asset tokens store assets by reference via inner storage. An asset entry on the storage is stored via a &lt;code&gt;uint64&lt;&#x2F;code&gt; mapping to asset data.&lt;&#x2F;p&gt;
&lt;p&gt;An asset array is an array of these &lt;code&gt;uint64&lt;&#x2F;code&gt; asset ID references.&lt;&#x2F;p&gt;
&lt;p&gt;Such a structure allows that, a generic asset can be added to the storage one time, and a reference to it can be added to the token contract as many times as we desire. Implementers can then use string concatenation to procedurally generate a link to a content-addressed archive based on the base &lt;em&gt;SRC&lt;&#x2F;em&gt; in the asset and the &lt;em&gt;token ID&lt;&#x2F;em&gt;. Storing the asset in a new token will only take 16 bytes of storage in the asset array per token for recurrent as well as &lt;code&gt;tokenId&lt;&#x2F;code&gt; dependent assets.&lt;&#x2F;p&gt;
&lt;p&gt;Structuring token&#x27;s assets in such a way allows for URIs to be derived programmatically through concatenation, especially when they differ only by &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;propose-commit-pattern-for-asset-addition&quot;&gt;Propose-Commit pattern for asset addition&lt;&#x2F;h3&gt;
&lt;p&gt;Adding assets to an existing token MUST be done in the form of a propose-commit pattern to allow for limited mutability by a 3rd party. When adding an asset to a token, it is first placed in the &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; array, and MUST be migrated to the &lt;em&gt;&quot;Active&quot;&lt;&#x2F;em&gt; array by the token&#x27;s owner. The &lt;em&gt;&quot;Pending&quot;&lt;&#x2F;em&gt; assets array SHOULD be limited to 128 slots to prevent spam and griefing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;asset-management&quot;&gt;Asset management&lt;&#x2F;h3&gt;
&lt;p&gt;Several functions for asset management are included. In addition to permissioned migration from &quot;Pending&quot; to &quot;Active&quot;, the owner of a token MAY also drop assets from both the active and the pending array -- an emergency function to clear all entries from the pending array MUST also be included.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The MultiAsset token standard has been made compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; in order to take advantage of the robust tooling available for implementations of ERC-721 and to ensure compatibility with existing ERC-721 infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;.&#x2F;assets&#x2F;test&#x2F;multiasset.ts&quot;&gt;&lt;code&gt;multiasset.ts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To run them in terminal, you can use the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;assets&#x2F;eip-5773&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npx hardhat test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5773&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;MultiAssetToken.sol&quot;&gt;&lt;code&gt;MultiAssetToken.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; apply: hidden logic may be present in any of the functions, including burn, add asset, accept asset, and more.&lt;&#x2F;p&gt;
&lt;p&gt;Caution is advised when dealing with non-audited contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>The &#x27;window.evmproviders&#x27; object</title>
        <published>2022-10-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Kosala Hemachandra</name><uri>https://github.com/kvhnuke</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5749/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5749-deprecate-window-ethereum/11195" />
        

        <id>https://wg-eips.ritovision.com/5749/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5749"
            label="EIP-5749" />
        

        
        

        
        <summary type="html">Add &#x27;window.evmproviders&#x27; and suggest the eventual removal of &#x27;window.ethereum&#x27;</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5749/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A Javascript Ethereum Provider interface injection that will allow for the interoperability of multiple browser wallets at the same time. Replacing &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; with &lt;code&gt;window.evmproviders&lt;&#x2F;code&gt; is a simple solution that will provide multiple benefits including: improving user experience, encouraging innovation in the space, removing race conditions and a &#x27;winner-takes-most&#x27; environment as well as lowering barriers for user adoption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;At present, &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; is the prevailing method by which Ethereum-compatible applications interact with injected wallets. This originated with Mist Wallet in 2015 to interact with other applications. With the proliferation of both applications and wallets, &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; has unintended negative consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;window.ethereum&lt;&#x2F;code&gt; only permits one wallet to be injected at a time, resulting in a race condition between two or more wallets. This creates an inconsistent connection behavior that makes having and using more than one browser wallet unpredictable and impractical. The current solution is for wallets to inject their own namespaces, but this is not feasible as every application would need to be made aware of any wallet that might be used.&lt;&#x2F;li&gt;
&lt;li&gt;The aforementioned race condition means users are disincentivized to experiment with new wallets. This creates a &#x27;winner-takes-most&#x27; wallet market across EVM chains which forces application developers to optimize for a particular wallet experience.&lt;&#x2F;li&gt;
&lt;li&gt;The &#x27;winner-takes-most&#x27; wallet environment that results from the &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; standard hinders innovation because it creates a barrier to adoption. New entrants into the space have difficulty gaining traction against legacy players because users can have no more than one injected wallet. With new entrants crowded out, legacy wallet providers are put under little pressure to innovate.&lt;&#x2F;li&gt;
&lt;li&gt;Wallets continue to be the most fundamental tool for interacting with blockchains. A homogeneous wallet experience in Ethereum and EVM chains risks stunting UX improvement across the ecosystem and will allow other ecosystems that are more encouraging of competition and innovation to move ahead.&lt;&#x2F;li&gt;
&lt;li&gt;Some wallets that currently use &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; as of August, 2022. Currently a user will have inconsistent behavior if they use multiple of these wallets in a single browser.
&lt;ul&gt;
&lt;li&gt;Metamask&lt;&#x2F;li&gt;
&lt;li&gt;Coinbase wallet&lt;&#x2F;li&gt;
&lt;li&gt;Enkrypt&lt;&#x2F;li&gt;
&lt;li&gt;Trust wallet&lt;&#x2F;li&gt;
&lt;li&gt;Rainbow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Replacing &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; with &lt;code&gt;window.evmproviders&lt;&#x2F;code&gt; will allow solutions such as web3modal and web3onboard to display all injected wallets the user has installed. This will simplify the UX and remove race conditions between wallet providers in case multiple wallets are installed. Over time, as &lt;code&gt;window.evmproviders&lt;&#x2F;code&gt; supplants the current standard and removes barriers to choice, we can hope to see a wallet landscape more reflective of user preference.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;window-evmproviders&quot;&gt;&lt;code&gt;window.evmproviders={}&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Represents the assets needed to display a wallet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * A UUIDv4 unique to the wallet provider.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * This must remain the same across versions but must be different across channels. For example, MetaMask, Trust wallet and Enkrypt should each have different UUIDs, but MetaMask 10.22.2 and MetaMask 9.8.1 should have the same UUID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;readonly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    uuid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The name of the wallet provider (e.g. `MetaMask` or `Enkrypt`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;readonly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * A base64 encoded SVG image.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Base64 is defined in RFC 4648.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;readonly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    icon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;data:image&#x2F;svg+xml;base64,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * A description of the wallet provider.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;readonly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Represents the new Provider with info type that extends the EIP1193 provider&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderWithInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; EIP1193Provider&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  	info&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderInfo&lt;&#x2F;span&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;Type &lt;code&gt;EIP1193Provider&lt;&#x2F;code&gt; is documented at &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * The type of `window.evmproviders`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EVMProviders&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * The key is RECOMMENDED to be the name of the extension in snake_case. It MUST contain only lowercase letters, numbers, and underscores.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   *&#x2F;&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 class=&quot;z-variable&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderWithInfo&lt;&#x2F;span&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Standardizing a &lt;code&gt;ProviderInfo&lt;&#x2F;code&gt; type allows determining the necessary information to populate a wallet selection popup. This is particularly useful for web3 onboarding libraries such as Web3Modal, Web3React, and Web3Onboard.&lt;&#x2F;p&gt;
&lt;p&gt;The name &lt;code&gt;evmproviders&lt;&#x2F;code&gt; was chosen to include other EVM-compliant chains.&lt;&#x2F;p&gt;
&lt;p&gt;The SVG image format was chosen for its flexibility, lightweight nature, and dynamic resizing capabilities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP doesn&#x27;t require supplanting &lt;code&gt;window.ethereum&lt;&#x2F;code&gt;, so it doesn&#x27;t directly break existing applications. However, the recommended behavior of eventually supplanting &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; would break existing applications that rely on it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;injection&quot;&gt;Injection&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderWithInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;your&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;evmproviders&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;evmproviders&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;evmproviders&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;retrieving-all-evm-providers&quot;&gt;Retrieving all EVM providers&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; allproviders&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Object&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;values&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;evmproviders&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;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The security considerations of EIP-1193 apply to this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;The use of SVG images introduces a cross-site scripting risk as they can include JavaScript code. Applications and libraries must render SVG images using the &lt;code&gt;&amp;lt;img&amp;gt;&lt;&#x2F;code&gt; tag to ensure no JS executions can happen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>General Extensibility for Method Behaviors</title>
        <published>2022-10-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Zainan Victor Zhou</name><uri>https://github.com/xinbenlv</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5750/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-5750-method-with-extra-data/11176" />
        

        <id>https://wg-eips.ritovision.com/5750/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5750"
            label="ERC-5750" />
        

        
        

        
        <summary type="html">Designating last param of dynamically sized bytes to be used for behavior extensions of methods.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5750/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes the passing of unstructured call data to functions to enable future extensibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The purpose of having extra data in a method is to allow further extensions to existing method interfaces.&lt;&#x2F;p&gt;
&lt;p&gt;It is it useful to make methods extendable. Any methods complying with this EIP, such as overloaded &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;vote&lt;&#x2F;code&gt; could use string reasons as the extra data. Existing EIPs that have exported methods compliant with this EIP can be extended for behaviors such as using the extra data to prove endorsement, as a salt, as a nonce, or as a commitment for a reveal&#x2F;commit scheme. Finally, data can be passed forward to callbacks.&lt;&#x2F;p&gt;
&lt;p&gt;There are two ways to achieve extensibility for existing functions. Each comes with their set of challenges:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add a new method&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;What will the method name be?&lt;&#x2F;li&gt;
&lt;li&gt;What will the parameters be?&lt;&#x2F;li&gt;
&lt;li&gt;How many use-cases does a given method signature support?&lt;&#x2F;li&gt;
&lt;li&gt;Does this support off-chain signatures?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Use one or more existing parameters, or add one or more new ones&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Should existing parameters be repurposed, or should more be added?&lt;&#x2F;li&gt;
&lt;li&gt;How many parameters should be used?&lt;&#x2F;li&gt;
&lt;li&gt;What are their sizes and types?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Standardizing how methods can be extended helps to answer these questions.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, this EIP aims to achieve maximum backward and future compatibility. Many EIPs already partially support this EIP, such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;. This EIP supports many use cases, from commit-reveal schemes (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5732&#x2F;&quot;&gt;EIP-5732&lt;&#x2F;a&gt;), to adding digital signatures alongside with a method call. Other implementers and EIPs should be able to depend on the compatibility granted by this EIP so that all compliant method interfaces are eligible for future new behaviors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;When used in this EIP, the term &lt;code&gt;bytes&lt;&#x2F;code&gt; MUST be interpreted as the dynamically-sized byte array in Solidity data types.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Unlike many other ERCs which is compliant at the &lt;code&gt;contract&lt;&#x2F;code&gt; level, this ERC&#x27;s specification specify compliance at &lt;code&gt;method&lt;&#x2F;code&gt; level.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any method with a bytes as this method&#x27;s last parameter is an &lt;em&gt;eligible&lt;&#x2F;em&gt; method. It looks like this &lt;code&gt;function methodName(type1 value1, type2 value2, ... bytes data)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;compliant&lt;&#x2F;em&gt; method MUST be an &lt;em&gt;eligible&lt;&#x2F;em&gt; method and MUST also designate that last &lt;code&gt;bytes&lt;&#x2F;code&gt; field in its method parameter for behaviors extensions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If an &lt;em&gt;eligible&lt;&#x2F;em&gt; method has an overloaded sibling method that
has the exact same method name and exact same preceding parameters
except for not having the last &lt;code&gt;bytes&lt;&#x2F;code&gt; parameter, the behavior
of the compliant method MUST be identical to
its overloaded sibling method when last &lt;code&gt;bytes&lt;&#x2F;code&gt; is an empty array.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;examples-of-compliant-and-non-compliant-methods&quot;&gt;Examples of compliant and non-compliant methods&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Here is a compliant method &lt;code&gt;methodName1&lt;&#x2F;code&gt; in a &lt;code&gt;Foo&lt;&#x2F;code&gt; contract&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This method allows extension behavior via `_data` field;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; firstNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; secondNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Here is a compliant method &lt;code&gt;methodName2&lt;&#x2F;code&gt; in a &lt;code&gt;Bar&lt;&#x2F;code&gt; contract which is an overloaded method for another &lt;code&gt;methodName2&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This is a sibling method to `methodName2(uint256 _param1, address _param2, bytes calldata _data);`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This method allows extension behavior via `_data` field;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When passed in an empty array for `_data` field, this method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      MUST behave IDENTICAL to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      its overloaded sibling `methodName2(uint256 _param1, address _param2);`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; firstNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; secondNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Here is a non-compliant method &lt;code&gt;methodName1&lt;&#x2F;code&gt; because it do not allow extending behavior&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This method DO NOT allow extension behavior via `_data` field;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; firstNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; secondNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Here is a non-compliant method
&lt;code&gt;methodName2(uint256 _param1, address _param2, bytes calldata _data);&lt;&#x2F;code&gt;
because it behaves differently
to its overloaded sibling method
&lt;code&gt;methodName2(uint256 _param1, address _param2);&lt;&#x2F;code&gt; when &lt;code&gt;_data&lt;&#x2F;code&gt; is empty array.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This is a sibling method to `methodName2(uint256 _param1, address _param2, bytes calldata _data);`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @dev This method allows extension behavior via `_data` field;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      When passed in an empty array for `_data` field, this method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      behave DIFFERENTLY to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      its overloaded sibling `methodName2(uint256 _param1, address _param2);`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; methodName2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _param2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; firstNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; secondNonRelatedMethod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; someValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Using the dynamically-sized &lt;code&gt;bytes&lt;&#x2F;code&gt; type allows for maximum flexibility by enabling payloads of arbitrary types.&lt;&#x2F;li&gt;
&lt;li&gt;Having the bytes specified as the last parameter makes this EIP compatible with the calldata layout of solidity.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Many existing EIPs already have compliant methods as part of their specification. All contracts compliant with those EIPs are either fully or partially compliant with this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an incomplete list:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;, the following method is already compliant:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;&lt;&#x2F;code&gt; is already compliant&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;, the following methods are already compliant
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;EIP-777&lt;&#x2F;a&gt;, the following methods are already compliant
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function burn(uint256 amount, bytes calldata data) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;function send(address to, uint256 amount, bytes calldata data) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;However, not all functions that have a &lt;code&gt;bytes&lt;&#x2F;code&gt; as the last parameter are compliant. The following functions are not compliant without an overload since their last parameter is involved in functionality:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;&quot;&gt;EIP-2535&lt;&#x2F;a&gt;, the following methods is not compliant:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Either&lt;&#x2F;strong&gt; of the following can be done to create a compliance.
&lt;ol&gt;
&lt;li&gt;An overload MUST be created: &lt;code&gt;function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata, bytes calldata _data) external;&lt;&#x2F;code&gt; which adds a new &lt;code&gt;_data&lt;&#x2F;code&gt; after all parameters of original method.&lt;&#x2F;li&gt;
&lt;li&gt;The use of &lt;code&gt;bytes memory _calldata&lt;&#x2F;code&gt; MUST be relaxed to allow for extending behaviors.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;EIP-1271&lt;&#x2F;a&gt;, the following method is not compliant:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue);&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Either&lt;&#x2F;strong&gt; of the following can be done to create a compliance:
&lt;ol&gt;
&lt;li&gt;An new overload MUST be created: &lt;code&gt;function isValidSignature(bytes32 _hash, bytes memory _signature, bytes calldata _data) public view returns (bytes4 magicValue);&lt;&#x2F;code&gt; which adds a new &lt;code&gt;_data&lt;&#x2F;code&gt; after all parameters of original method.&lt;&#x2F;li&gt;
&lt;li&gt;The use of &lt;code&gt;bytes memory _signature&lt;&#x2F;code&gt; MUST be relaxed to allow for extending behaviors.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;If using the extra data for extended behavior, such as supplying signature for onchain verification, or supplying commitments in a commit-reveal scheme, best practices should be followed for those particular extended behaviors.&lt;&#x2F;li&gt;
&lt;li&gt;Compliant contracts must also take into consideration that the data parameter will be publicly revealed when submitted into the mempool or included in a block, so one must consider the risk of replay and transaction ordering attacks. &lt;strong&gt;Unencrypted personally identifiable information must never be included in the data parameter.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Process for Approving External Resources</title>
        <published>2022-09-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Sam Wilson</name><uri>https://github.com/SamWilsn</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5757/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5757-process-for-approving-external-resources/11215" />
        

        <id>https://wg-eips.ritovision.com/5757/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5757"
            label="EIP-5757" />
        

        
        

        
        <summary type="html">Requirements and process for allowing new origins of external resources</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5757/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum improvement proposals (EIPs) occasionally link to resources external to this repository. This document sets out the requirements for origins that may be linked to, and the process for approving a new origin.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Link&lt;&#x2F;strong&gt;: Any method of referring to a resource, including: markdown links, anchor tags (&lt;code&gt;&amp;lt;a&amp;gt;&lt;&#x2F;code&gt;), images, citations of books&#x2F;journals, and any other method of referencing content not in the current resource.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Resource&lt;&#x2F;strong&gt;: A web page, document, article, file, book, or other media that contains content.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Origin&lt;&#x2F;strong&gt;: A publisher&#x2F;chronicler of resources, like a standards body (eg. w3c) or a system of referring to documents (eg. Digital Object Identifier System).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;requirements-for-origins&quot;&gt;Requirements for Origins&lt;&#x2F;h3&gt;
&lt;p&gt;Permissible origins &lt;strong&gt;MUST&lt;&#x2F;strong&gt; provide a method of uniquely identifying a particular revision of a resource. Examples of such methods may include git commit hashes, version numbers, or publication dates.&lt;&#x2F;p&gt;
&lt;p&gt;Permissible origins &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have a proven history of availability. A origin existing for at least ten years and reliably serving resources would be sufficient—but not necessary—to satisfy this requirement.&lt;&#x2F;p&gt;
&lt;p&gt;Permissible origins &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; charge a fee for accessing resources.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;origin-removal&quot;&gt;Origin Removal&lt;&#x2F;h3&gt;
&lt;p&gt;Any approved origin that ceases to satisfy the above requirements &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be removed from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1&#x2F;&quot;&gt;EIP-1&lt;&#x2F;a&gt;. If a removed origin later satisfies the requirements again, it MAY be re-approved by following the process described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5757&#x2F;#origin-approval&quot;&gt;Origin Approval&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Finalized EIPs (eg. those in the &lt;code&gt;Final&lt;&#x2F;code&gt; or &lt;code&gt;Withdrawn&lt;&#x2F;code&gt; statuses) &lt;strong&gt;SHOULD NOT&lt;&#x2F;strong&gt; be updated to remove links to these origins.&lt;&#x2F;p&gt;
&lt;p&gt;Non-Finalized EIPs &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remove links to these origins before changing statuses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;origin-approval&quot;&gt;Origin Approval&lt;&#x2F;h3&gt;
&lt;p&gt;Should the editors determine that an origin meets the requirements above, EIP-1 &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be updated to include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The name of the allowed origin;&lt;&#x2F;li&gt;
&lt;li&gt;The permitted markup and formatting required when referring to resources from the origin; and&lt;&#x2F;li&gt;
&lt;li&gt;A fully rendered example of what a link should look like.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;unique-identifiers&quot;&gt;Unique Identifiers&lt;&#x2F;h3&gt;
&lt;p&gt;If it is impossible to uniquely identify a version of a resource, it becomes impractical to track changes, which makes it difficult to ensure immutability.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;availability&quot;&gt;Availability&lt;&#x2F;h3&gt;
&lt;p&gt;If it is possible to implement a standard without a linked resource, then the linked resource is unnecessary. If it is impossible to implement a standard without a linked resource, then that resource must be available for implementers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;free-access&quot;&gt;Free Access&lt;&#x2F;h3&gt;
&lt;p&gt;The Ethereum ecosystem is built on openness and free access, and the EIP process should follow those principles.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Commit Interface</title>
        <published>2022-09-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Zainan Victor Zhou</name><uri>https://github.com/xinbenlv</uri>
	</author>
	
	<author>
		<name>Matt Stam</name><uri>https://github.com/mattstam</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5732/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-5732-simple-commit-interface-to-support-commit-reveal-schemes/11115" />
        

        <id>https://wg-eips.ritovision.com/5732/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5732"
            label="ERC-5732" />
        

        
        

        
        <summary type="html">A simple but general commit interface to support commit-reveal scheme.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5732/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A simple commit interface to support commit-reveal scheme which provides &lt;strong&gt;only&lt;&#x2F;strong&gt; a commit
method but no reveal method, allowing implementations to integrate this interface
with arbitrary reveal methods such as &lt;code&gt;vote&lt;&#x2F;code&gt; or &lt;code&gt;transfer&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;support commit-reveal privacy for applications such as voting.&lt;&#x2F;li&gt;
&lt;li&gt;make it harder for attackers for front-running, back-running or sandwich attacks.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;Interfaces referenced in this specification are as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.7.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is 0xf14fcbc8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC_COMMIT_CORE&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _commitment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.7.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is 0x67b2ec2c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC_COMMIT_GENERAL&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _timePoint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _commitment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _extraData&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commitFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _commitment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _extraData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; timePoint&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;A compliant contract MUST implement the &lt;code&gt;IERC_COMMIT_CORE&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A compliant contract SHOULD implement the &lt;code&gt;IERC_COMMIT_GENERAL&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A compliant contract that implements the &lt;code&gt;IERC_COMMIT_GENERAL&lt;&#x2F;code&gt; interface MUST accept &lt;code&gt;commit(_commitment)&lt;&#x2F;code&gt; as equivalent to &lt;code&gt;commitFrom(msg.sender, _commitment, [&#x2F;*empty array*&#x2F;])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;timePoint&lt;&#x2F;code&gt; return value of &lt;code&gt;commitFrom&lt;&#x2F;code&gt; is RECOMMENDED to use &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; or &lt;code&gt;block.number&lt;&#x2F;code&gt; or a number that indicates the ordering of different commitments. When &lt;code&gt;commitFrom&lt;&#x2F;code&gt; is being called.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A compliant contract that implements &lt;code&gt;IERC_COMMIT_GENERAL&lt;&#x2F;code&gt; MUST emit event &lt;code&gt;Commit&lt;&#x2F;code&gt; when a commitment is accepted and recorded. In the parameter of both &lt;code&gt;Commit&lt;&#x2F;code&gt; and the &lt;code&gt;commitFrom&lt;&#x2F;code&gt; method, the &lt;code&gt;_timePoint&lt;&#x2F;code&gt; is a time-point-representing value that represents ordering of commitments in which a latter commitment will always have a &lt;em&gt;greater or equal value&lt;&#x2F;em&gt; than a former commitment, such as &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; or &lt;code&gt;block.number&lt;&#x2F;code&gt; or other time scale chosen by implementing contracts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;extraData&lt;&#x2F;code&gt; is reserved for future behavior extension. If the &lt;code&gt;_from&lt;&#x2F;code&gt; is different from the TX signer, it is RECOMMENDED that compliant contract SHOULD validate signature for &lt;code&gt;_from&lt;&#x2F;code&gt;. For EOAs this will be validating its ECDSA signatures on chain. For smart contract accounts, it is RECOMMENDED to use &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;EIP-1271&lt;&#x2F;a&gt; to validate the signatures.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;One or more methods of a compliant contract MAY be used for reveal.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;But there MUST be a way to supply an extra field of &lt;code&gt;secret_salt&lt;&#x2F;code&gt;, so that committer can later open the &lt;code&gt;secret_salt&lt;&#x2F;code&gt; in the reveal TX that exposes the &lt;code&gt;secret_salt&lt;&#x2F;code&gt;. The size and location of &lt;code&gt;secret_salt&lt;&#x2F;code&gt; is intentionally unspecified in this EIP to maximize flexibility for integration.&lt;&#x2F;p&gt;
&lt;ol start=&quot;8&quot;&gt;
&lt;li&gt;It is RECOMMENDED for compliant contracts to implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;One design options is that we can attach a Commit Interface to any individual ERCs such as voting standards or token standards. We choose to have a simple and generalize commit interface so all ERCs can be extended to support commit-reveal without changing their basic method signatures.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The key derived design decision we made is we will have  a standardized &lt;code&gt;commit&lt;&#x2F;code&gt; method without a standardized &lt;code&gt;reveal&lt;&#x2F;code&gt; method, making room for customized reveal method or using &lt;code&gt;commit&lt;&#x2F;code&gt; with existing standard.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We chose to have a simple one parameter method of &lt;code&gt;commit&lt;&#x2F;code&gt; in our Core interface to make it fully backward compatible with a few prior-adoptions e.g. ENS&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We also add a &lt;code&gt;commitFrom&lt;&#x2F;code&gt; to easy commitment being generated off-chain and submitted by some account on behalf by another account.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is backward compatible with all existing ERCs method signature that has extraData. New EIPs can be designed with an extra field of &quot;salt&quot; to make it easier to support this EIP, but not required.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;IERC_COMMIT_CORE&lt;&#x2F;code&gt; is backward compatible with ENS implementations and other existing prior-art.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;commit-with-ens-register-as-reveal&quot;&gt;Commit with ENS Register as Reveal&lt;&#x2F;h3&gt;
&lt;p&gt;In ENS registering process, currently inside of &lt;code&gt;ETHRegistrarController&lt;&#x2F;code&gt; contract a commit function is being used to allow registerer fairly register a desire domain to avoid being front-run.&lt;&#x2F;p&gt;
&lt;p&gt;Here is how ENS uses commitment in its registration logic:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;commitments&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; maxCommitmentAge &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; now&lt;&#x2F;span&gt;&lt;span&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&gt;    commitments&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; now&lt;&#x2F;span&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;With this EIP it can be updated to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commitment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;commitments&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; maxCommitmentAge &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; now&lt;&#x2F;span&gt;&lt;span&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&gt;    commitments&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; now&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Do not use the reference implementation in production. It is just for demonstration purposes.&lt;&#x2F;li&gt;
&lt;li&gt;The reveal transactions and parameters, especially &lt;code&gt;secret_salt&lt;&#x2F;code&gt;, MUST be kept secret before they are revealed.&lt;&#x2F;li&gt;
&lt;li&gt;The length of &lt;code&gt;secret_salt&lt;&#x2F;code&gt; must be cryptographically long enough and the random values used to generate &lt;code&gt;secret_salt&lt;&#x2F;code&gt; must be cryptographically safe.&lt;&#x2F;li&gt;
&lt;li&gt;Users must NEVER reuse a used &lt;code&gt;secret_salt&lt;&#x2F;code&gt;. It&#x27;s recommended for client applications to warn users who attempt to do so.&lt;&#x2F;li&gt;
&lt;li&gt;Contract implementations should consider deleting the commitment of a given sender immediately to reduce the chances of a replay attack or re-entry attack.&lt;&#x2F;li&gt;
&lt;li&gt;Contract implementations may consider including the ordering of commitment received to add restrictions on the order of reveal transactions.&lt;&#x2F;li&gt;
&lt;li&gt;There is potential for replay attacks across different chainIds or chains resulting from forks. In these cases, the chainId must be included in the generation of commitment. For applications with a higher risk of replay attacks, implementors should consider battle-tested and cryptographically-secure solutions such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; to compose commitments before creating their own new solution.&lt;&#x2F;li&gt;
&lt;li&gt;Proper time gaps are suggested if the purpose is to avoid frontrunning attacks.&lt;&#x2F;li&gt;
&lt;li&gt;For compliant contract that requires the &lt;code&gt;_timePoint&lt;&#x2F;code&gt; from the next transaction to be &lt;em&gt;strictly greater&lt;&#x2F;em&gt; than that of any previous transaction, &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; and &lt;code&gt;block.number&lt;&#x2F;code&gt; are not reliable as two transactions could co-exist in the same block resulting in the same &lt;code&gt;_timePoint&lt;&#x2F;code&gt; value. In such case, extra measures to enforce this strict monotonicity are required, such as the use of a separate sate variable in the contract to keep track of number of commits it receives, or to reject any second&#x2F;other TX that shares the same &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; or &lt;code&gt;block.number&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Token Minting and Burning</title>
        <published>2022-09-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Zainan Victor Zhou</name><uri>https://github.com/xinbenlv</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5679/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-5679-mint-and-burn-tokens/10913" />
        

        <id>https://wg-eips.ritovision.com/5679/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5679"
            label="ERC-5679" />
        

        
        

        
        <summary type="html">An extension for minting and burning EIP-20, EIP-721, and EIP-1155 tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5679/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a consistent way to extend token standards for minting and burning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Minting and Burning are typical actions for creating and destroying tokens.
By establishing a consistent way to mint and burn a token, we complete the basic lifecycle.&lt;&#x2F;p&gt;
&lt;p&gt;Some implementations of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;
have been able to use &lt;code&gt;transfer&lt;&#x2F;code&gt; methods or the-like
to mint and burn tokens. However, minting and burning change token supply. The access controls
of minting and burning also usually follow different rules than transfer.
Therefore, creating separate methods for burning and minting simplifies implementations
and reduces security error.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Any contract complying with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; when extended with this EIP,
&lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is 0xd0017968&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5679Ext20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Any contract complying with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; when extended with this EIP,
&lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is 0xcce39764&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5679Ext721&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Any contract complying with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; when extended with this EIP,
&lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The EIP-165 identifier of this interface is 0xf4cedd5a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5679Ext1155&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMintBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;   function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burnBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;
&lt;p&gt;When the token is being minted, the transfer events &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be emitted as if
the token in the &lt;code&gt;_amount&lt;&#x2F;code&gt; for EIP-20 and EIP-1155 and token id being &lt;code&gt;_id&lt;&#x2F;code&gt; for EIP-721 and EIP-1155
were transferred from address &lt;code&gt;0x0&lt;&#x2F;code&gt; to the recipient address identified by &lt;code&gt;_to&lt;&#x2F;code&gt;.
The total supply &lt;strong&gt;MUST&lt;&#x2F;strong&gt; increase accordingly.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When the token is being burned, the transfer events &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be emitted as if
the token in the &lt;code&gt;_amount&lt;&#x2F;code&gt; for EIP-20 and EIP-1155 and token id being &lt;code&gt;_id&lt;&#x2F;code&gt; for EIP-721 and EIP-1155
were transferred from the recipient address identified by &lt;code&gt;_to&lt;&#x2F;code&gt; to the address of &lt;code&gt;0x0&lt;&#x2F;code&gt;.
The total supply &lt;strong&gt;MUST&lt;&#x2F;strong&gt; decrease accordingly.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;safeMint&lt;&#x2F;code&gt; MUST implement the same receiver restrictions as &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; as defined in
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It&#x27;s RECOMMENDED for the client to implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt; identifiers as specified above.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It&#x27;s possible that the interface be consolidated to the same as EIP-1155 which is always bearing &lt;code&gt;_amount&lt;&#x2F;code&gt; field,
regardless of whether it&#x27;s a EIP-20, EIP-721 or EIP-1155. But we choose that each ERC token should have their own
standard way of representing the amount of token to follow the same way of &lt;code&gt;_id&lt;&#x2F;code&gt; and &lt;code&gt;_amount&lt;&#x2F;code&gt; in their original
token standard.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We have chosen to identify the interface with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt; identifiers each individually,
instead of having a single identifier because the signatures of interface are different.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We have chosen NOT to create new events but to require the usage of existing transfer event as required by EIP-20
EIP-721 and EIP-1155 for maximum compatibility.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We have chosen to add &lt;code&gt;safeMintBatch&lt;&#x2F;code&gt; and &lt;code&gt;burnBatch&lt;&#x2F;code&gt; methods for EIP-1155 but not for EIP-721 to follow the
convention of EIP-721 and EIP-1155 respectively.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We have not add extension for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;EIP-777&lt;&#x2F;a&gt; because it already handles Minting and Burning.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is designed to be compatible for EIP-20, EIP-721 and EIP-1155 respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP depends on the security soundness of the underlying book keeping behavior of the token implementation.
In particular, a token contract should carefully design the access control for which role is granted permission
to mint a new token. Failing to safe guard such behavior can cause fraudulent issuance and an elevation of total supply.&lt;&#x2F;p&gt;
&lt;p&gt;The burning should also carefully design the access control. Typically only the following two roles are entitled to burn a token:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Role 1. The current token holder&lt;&#x2F;li&gt;
&lt;li&gt;Role 2. An role with special privilege.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Either Role 1 OR Role 2 or a consensus between the two are entitled to conduct the burning action.
However as author of this EIP we do recognize there are potentially other use case where a third type of role shall be entitled
to burning. We keep this EIP less opinionated in such restriction but implementors should be cautious about designing
the restriction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Token State Fingerprint</title>
        <published>2022-09-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Naim Ashhab</name><uri>https://github.com/ashhanai</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5646/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5646-discussion-token-state-fingerprint/10808" />
        

        <id>https://wg-eips.ritovision.com/5646/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5646"
            label="ERC-5646" />
        

        
        

        
        <summary type="html">Unambiguous token state identifier</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5646/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines the minimum interface required to unambiguously identify the state of a mutable token without knowledge of implementation details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, protocols need to know about tokens&#x27; state properties to create the unambiguous identifier. Unfortunately, this leads to an obvious bottleneck in which protocols need to support every new token specifically.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5646&#x2F;.&#x2F;assets&#x2F;support-per-abi.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5646&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Function to return current token state fingerprint.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Id of a token state in &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;question&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Current&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token state fingerprint.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getStateFingerprint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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;&#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;ul&gt;
&lt;li&gt;&lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; MUST return a different value when the token state changes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; MUST NOT return a different value when the token state remains the same.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; MUST include all state properties that might change during the token lifecycle (are not immutable).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; MAY include computed values, such as values based on a current timestamp (e.g., expiration, maturity).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; MAY include token metadata URI.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;supportsInterface(0xf5112315)&lt;&#x2F;code&gt; MUST return &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Protocols can use state fingerprints as a part of a token identifier and support mutable tokens without knowing any state implementation details.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5646&#x2F;.&#x2F;assets&#x2F;support-per-eip.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;State fingerprints don&#x27;t have to factor in state properties that are immutable, because they can be safely identified by a token id.&lt;&#x2F;p&gt;
&lt;p&gt;This standard is not for use cases where token state property knowledge is required, as these cases cannot escape the bottleneck problem described earlier.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is not introducing any backward incompatibilities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example of a mutable token implementing state fingerprint.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; LPToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC5646&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Stored token states (token id =&amp;gt; state).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; states&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; State&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; asset1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; asset2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; amount1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; amount2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; fee&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Immutable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Immutable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; expiration&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Parameter dependent on a block.timestamp&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; State fingerprint getter.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Id of a token state in &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;question&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Current&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token state fingerprint.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getStateFingerprint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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&gt;        State &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; state &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; states&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;asset1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;asset2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; state.fee don&amp;#39;t need to be part of the fingerprint computation as it is immutable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; state.operator don&amp;#39;t need to be part of the fingerprint computation as it is immutable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;                block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expiration&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;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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ERC5646&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Token state fingerprints from two different contracts may collide. Because of that, they should be compared only in the context of one token contract.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;getStateFingerprint&lt;&#x2F;code&gt; implementation does not include all parameters that could change the token state, a token owner would be able to change the token state without changing the token fingerprint. It could break the trustless assumptions of several protocols, which create, e.g., buy offers for tokens. The token owner would be able to change the state of the token before accepting an offer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>NFT Metadata JSON Schema dStorage Extension</title>
        <published>2022-09-08T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin Fu</name><uri>https://github.com/gavfu</uri>
	</author>
	
	<author>
		<name>Leo Wang</name><uri>https://github.com/wanglie1986</uri>
	</author>
	
	<author>
		<name>Bova Chen</name><uri>https://github.com/appoipp</uri>
	</author>
	
	<author>
		<name>Guang Han</name><uri>https://github.com/pangwa</uri>
	</author>
	
	<author>
		<name>Brian Wu</name><uri>https://github.com/wuhaixian1984</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5625/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5625-nft-metadata-json-schema-dstorage-extension/10754" />
        

        <id>https://wg-eips.ritovision.com/5625/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5625"
            label="ERC-5625" />
        

        
        

        
        <summary type="html">Add a dStorage property to non-fungible tokens (NFTs) metadata JSON schema to provide decentralized storage information of NFT assets</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5625/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP extends the NFT metadata JSON schema defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;, adding a &lt;code&gt;dStorage&lt;&#x2F;code&gt; key that provides information about how the NFT data is stored.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As highly valuable crypto properties, NFT assets intrinsically demand guaranteed storage to assure their &lt;strong&gt;immutability&lt;&#x2F;strong&gt;, &lt;strong&gt;reliability&lt;&#x2F;strong&gt;, and &lt;strong&gt;durability&lt;&#x2F;strong&gt;. NFT ownership is tracked by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; smart contracts, hence persisted in blockchain, which is not a problem. But how about the mime-type assets that NFT tokens represent? Ideally, they should also be stored in some reliable and verifiable decentralized storage system that is designed to store larger amounts of data than the blockchain itself. As an effort to promote &lt;strong&gt;decentralized storage&lt;&#x2F;strong&gt; adoption in NFT world, we propose to add additional &lt;strong&gt;dStorage&lt;&#x2F;strong&gt; information into NFT metadata JSON schema.&lt;&#x2F;p&gt;
&lt;p&gt;As a refresher, let&#x27;s review existing NFT metadata JSON schema standards. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; defines a standard contract method &lt;code&gt;tokenURI&lt;&#x2F;code&gt; to return a given NFT&#x27;s metadata JSON file, conforming to the &lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; Metadata JSON Schema&lt;&#x2F;em&gt;, which defines three properties: &lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;description&lt;&#x2F;code&gt; and &lt;code&gt;image&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; also defines a standard contract method &lt;code&gt;uri&lt;&#x2F;code&gt; to return NFT metadata JSON files conforming to the &lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; Metadata JSON Schema&lt;&#x2F;em&gt;, which defines properties like &lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;decimals&lt;&#x2F;code&gt;, &lt;code&gt;description&lt;&#x2F;code&gt;, &lt;code&gt;image&lt;&#x2F;code&gt;, &lt;code&gt;properties&lt;&#x2F;code&gt;, &lt;code&gt;localization&lt;&#x2F;code&gt;, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Besides, as the world&#x27;s largest NFT marketplace nowadays, OpenSea defines their own &lt;em&gt;Metadata Standards&lt;&#x2F;em&gt;, including a few more properties like &lt;code&gt;image_data&lt;&#x2F;code&gt;, &lt;code&gt;external_url&lt;&#x2F;code&gt;, &lt;code&gt;attributes&lt;&#x2F;code&gt;, &lt;code&gt;background_color&lt;&#x2F;code&gt;, &lt;code&gt;animation_url&lt;&#x2F;code&gt;, &lt;code&gt;youtube_url&lt;&#x2F;code&gt;, etc. This standard is de facto respected and followed by other NFT marketplaces like LooksRare.&lt;&#x2F;p&gt;
&lt;p&gt;None of these standards conveys storage information about the mime-type asset that the NFT token represents. This proposal is an effort to fill the missing part.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;In addition to the existing properties, the Metadata JSON file returned by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; smart contracts (via &lt;code&gt;tokenURI&lt;&#x2F;code&gt; and &lt;code&gt;uri&lt;&#x2F;code&gt; methods, respectively), should OPTIONALLY contains one more &lt;code&gt;dStorage&lt;&#x2F;code&gt; property.&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; smart contracts, the Metadata JSON file schema is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;dStorage&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;persistence_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;challenge_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;consensus&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dstorage_note&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dStorage platform name like Swarm, Arweave, Filecoin, Crust, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A brief description of the dStorage platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;persistence_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Persistence mechanism or incentive structure of the dStorage platform, like &amp;#39;blockchain-based&amp;#39;, &amp;#39;contract-based&amp;#39;, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;challenge_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Challenge mechanism of the dStorage platform, like Arweave&amp;#39;s proof-of-access, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;consensus&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Consensus mechanism of the dStorage platform, like PoW, PoS, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;dstorage_note&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A note to prove the storage of the NFT asset on the dStorage platform, like a Filecoin deal id, a Crust place_storage_order transaction hash, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;For &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; smart contracts, the Metadata JSON file schema is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Token Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;decimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The number of decimal places that the token amount should display - e.g. 18, means to divide the token amount by 1000000000000000000 to get its user representation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this token represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Arbitrary properties. Values may be strings, numbers, object or arrays.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;localization&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;locales&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The URI pattern to fetch localized data from. This URI should contain the substring `{locale}` which will be replaced with the appropriate locale value before sending the request.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The locale of the default data within the base JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;locales&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The list of locales for which data is available. These locales should conform to those defined in the Unicode Common Locale Data Repository (http:&#x2F;&#x2F;cldr.unicode.org&#x2F;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;dStorage&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;persistence_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;challenge_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;consensus&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dstorage_note&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dStorage platform name like Swarm, Arweave, Filecoin, Crust, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A brief description of the dStorage platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;persistence_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Persistence mechanism or incentive structure of the dStorage platform, like &amp;#39;blockchain-based&amp;#39;, &amp;#39;contract-based&amp;#39;, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;challenge_mechanism&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Challenge mechanism of the dStorage platform, like Arweave&amp;#39;s proof-of-access, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;consensus&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Consensus mechanism of the dStorage platform, like PoW, PoS, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;dstorage_note&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A note to prove the storage of the NFT asset on the dStorage platform, like a Filecoin deal id, a Crust place_storage_order transaction hash, etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;choice-between-interface-and-json-schema-extension&quot;&gt;Choice between Interface and JSON Schema Extension&lt;&#x2F;h3&gt;
&lt;p&gt;An extension of the EIP-721 or EIP-1155 contract interfaces would unnecessarily require additional code to implement, and would not be available for use by NFT projects that already have their NFT smart contracts finalized and deployed. An optional JSON schema extension is noninvasive, and more easily adopted.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h1&gt;
&lt;p&gt;This EIP is backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;  and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce any new security risks or vulnerabilities, as the &lt;code&gt;dStorage&lt;&#x2F;code&gt; property is only an informational field of the Metadata JSON file returned by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; smart contracts. It does not affect the execution or validity of NFT transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Transferable Vesting NFT</title>
        <published>2022-09-08T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Apeguru</name><uri>https://github.com/Apegurus</uri>
	</author>
	
	<author>
		<name>Marco De Vries</name><email>marco@paladinsec.co</email>
	</author>
	
	<author>
		<name>Mario</name><email>mario@paladinsec.co</email>
	</author>
	
	<author>
		<name>DeFiFoFum</name><uri>https://github.com/DeFiFoFum</uri>
	</author>
	
	<author>
		<name>Elliott Green</name><uri>https://github.com/elliott-green</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5725/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5725-transferable-vesting-nft/11099" />
        

        <id>https://wg-eips.ritovision.com/5725/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5725"
            label="ERC-5725" />
        

        
        

        
        <summary type="html">An interface for transferable vesting NFTs which release underlying tokens over time.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5725/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;strong&gt;Non-Fungible Token&lt;&#x2F;strong&gt; (NFT) standard used to vest tokens (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; or otherwise) over a vesting release curve.&lt;&#x2F;p&gt;
&lt;p&gt;The following standard allows for the implementation of a standard API for NFT based contracts that hold and represent the vested and locked properties of any underlying token (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; or otherwise) that is emitted to the NFT holder. This standard is an extension of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; token that provides basic functionality for creating vesting NFTs, claiming the tokens and reading vesting curve properties.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Vesting contracts, including timelock contracts, lack a standard and unified interface, which results in diverse implementations of such contracts. Standardizing such contracts into a single interface would allow for the creation of an ecosystem of on- and off-chain tooling around these contracts. In addition, liquid vesting in the form of non-fungible assets can prove to be a huge improvement over traditional &lt;strong&gt;Simple Agreement for Future Tokens&lt;&#x2F;strong&gt; (SAFTs) or &lt;strong&gt;Externally Owned Account&lt;&#x2F;strong&gt; (EOA)-based vesting as it enables transferability and the ability to attach metadata similar to the existing functionality offered by with traditional NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;Such a standard will not only provide a much-needed &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token lock standard, but will also enable the creation of secondary marketplaces tailored for semi-liquid SAFTs.&lt;&#x2F;p&gt;
&lt;p&gt;This standard also allows for a variety of different vesting curves to be implement easily.&lt;&#x2F;p&gt;
&lt;p&gt;These curves could represent:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;linear vesting&lt;&#x2F;li&gt;
&lt;li&gt;cliff vesting&lt;&#x2F;li&gt;
&lt;li&gt;exponential vesting&lt;&#x2F;li&gt;
&lt;li&gt;custom deterministic vesting&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;use-cases&quot;&gt;Use Cases&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;A framework to release tokens over a set period of time that can be used to build many kinds of NFT financial products such as bonds, treasury bills, and many others.&lt;&#x2F;li&gt;
&lt;li&gt;Replicating SAFT contracts in a standardized form of semi-liquid vesting NFT assets.
&lt;ul&gt;
&lt;li&gt;SAFTs are generally off-chain, while today&#x27;s on-chain versions are mainly address-based, which makes distributing vesting shares to many representatives difficult. Standardization simplifies this convoluted process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Providing a path for the standardization of vesting and token timelock contracts.
&lt;ul&gt;
&lt;li&gt;There are many such contracts in the wild and most of them differ in both interface and implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;NFT marketplaces dedicated to vesting NFTs.
&lt;ul&gt;
&lt;li&gt;Whole new sets of interfaces and analytics could be created from a common standard for token vesting NFTs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Integrating vesting NFTs into services like Safe Wallet.
&lt;ul&gt;
&lt;li&gt;A standard would mean services like Safe Wallet could more easily and uniformly support interactions with these types of contracts inside of a multisig contract.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Enable standardized fundraising implementations and general fundraising that sell vesting tokens (eg. SAFTs) in a more transparent manner.&lt;&#x2F;li&gt;
&lt;li&gt;Allows tools, front-end apps, aggregators, etc. to show a more holistic view of the vesting tokens and the properties available to users.
&lt;ul&gt;
&lt;li&gt;Currently, every project needs to write their own visualization of the vesting schedule of their vesting assets. If this is standardized, third-party tools could be developed to aggregate all vesting NFTs from all projects for the user, display their schedules and allow the user to take aggregated vesting actions.&lt;&#x2F;li&gt;
&lt;li&gt;Such tooling can easily discover compliance through the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; &lt;code&gt;supportsInterface(InterfaceID)&lt;&#x2F;code&gt; check.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Makes it easier for a single wrapping implementation to be used across all vesting standards that defines multiple recipients, periodic renting of vesting tokens etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;IERC721.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Non-Fungible Vesting Token Standard.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A non-fungible token standard used to vest ERC-20 tokens over a vesting release curve &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  scheduled using timestamps.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Because this standard relies on timestamps for the vesting schedule, it&amp;#39;s important to keep track of the &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  tokens claimed per Vesting NFT so that a user cannot withdraw more tokens than allotted for a specific Vesting NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@custom:interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-id 0xbd3a202b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5725&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  This event is emitted when the payout is claimed through the claim function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the NFT tokenId of the assets being claimed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address which is receiving the payout.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; claimAmount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of tokens being claimed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PayoutClaimed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimAmount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  This event is emitted when an `owner` sets an address to manage token claims for all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address setting a manager to manage all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address being permitted to manage all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean indicating whether the spender is approved to claim for all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  This event is emitted when an `owner` sets an address to manage token claims for a `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `owner` of `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address being permitted to manage a tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The unique identifier of the token being managed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean indicating whether the spender is approved to claim for `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Claim the pending payout for the NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST grant the claimablePayout value at the time of claim being called to `msg.sender`. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if not called by the token owner or approved users. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST emit PayoutClaimed. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  SHOULD revert if there is nothing to claim.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; claim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of tokens for the NFT which have been claimed at the current timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The total amount of payout tokens claimed for this NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; claimedPayout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of tokens for the NFT which can be claimed at the current timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is RECOMMENDED that this is calculated as the `vestedPayout()` subtracted from `payoutClaimed()`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The amount of unlocked payout tokens for the NFT which have not yet been claimed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; claimablePayout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Total amount of tokens which have been vested at the current timestamp. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  This number also includes vested tokens which have been claimed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is RECOMMENDED that this function calls `vestedPayoutAtTime` &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  with `block.timestamp` as the `timestamp` parameter.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Total amount of tokens which have been vested at the current timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; vestedPayout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Total amount of vested tokens at the provided timestamp. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  This number also includes vested tokens which have been claimed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `timestamp` MAY be both in the future and in the past. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  Zero MUST be returned if the timestamp is before the token was minted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The timestamp to check on, can be both in the past and the future.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Total amount of tokens which have been vested at the provided timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; vestedPayoutAtTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of tokens for an NFT which are currently vesting.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The sum of vestedPayout and vestingPayout SHOULD always be the total payout.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of tokens for the NFT which are vesting until a future date.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; vestingPayout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payout&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The start and end timestamps for the vesting of the provided NFT. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST return the timestamp where no further increase in vestedPayout occurs for `vestingEnd`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; vestingStart&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The beginning of the vesting as a unix timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; vestingEnd&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ending of the vesting as a unix timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; vestingPeriod&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vestingStart&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vestingEnd&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Token which is used to pay out the vesting claims.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; token&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token which is used to pay out the vesting claims.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; payoutToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; token&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets a global `operator` with permission to manage all tokens owned by the current `msg.sender`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to let manage all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean indicating whether the spender is approved to claim for all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setClaimApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets a tokenId `operator` with permission to manage a single `tokenId` owned by the `msg.sender`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to let manage a single `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the `tokenId` to be managed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A boolean indicating whether the spender is approved to claim for all tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setClaimApproval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if `owner` has set `operator` to manage all `tokenId`s.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The owner allowing `operator` to manage all `tokenId`s.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address who is given permission to spend tokens on behalf of the `owner`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isClaimApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isClaimApproved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the operating address for a `tokenId`. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  If `tokenId` is not managed, then returns the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT `tokenId` to query for a `tokenId` manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getClaimApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;terms&quot;&gt;Terms&lt;&#x2F;h3&gt;
&lt;p&gt;These are base terms used around the specification which function names and definitions are based on.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;vesting&lt;&#x2F;em&gt;: Tokens which a vesting NFT is vesting until a future date.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;vested&lt;&#x2F;em&gt;: Total amount of tokens a vesting NFT has vested.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;claimable&lt;&#x2F;em&gt;: Amount of vested tokens which can be unlocked.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;claimed&lt;&#x2F;em&gt;: Total amount of tokens unlocked from a vesting NFT.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;timestamp&lt;&#x2F;em&gt;: The unix &lt;code&gt;timestamp&lt;&#x2F;code&gt; (seconds) representation of dates used for vesting.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;vesting-functions&quot;&gt;Vesting Functions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;vestingPayout&lt;&#x2F;code&gt; + &lt;code&gt;vestedPayout&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;vestingPayout(uint256 tokenId)&lt;&#x2F;code&gt; and &lt;code&gt;vestedPayout(uint256 tokenId)&lt;&#x2F;code&gt; add up to the total number of tokens which can be claimed by the end of the vesting schedule. This is also equal to &lt;code&gt;vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)&lt;&#x2F;code&gt; with &lt;code&gt;type(uint256).max&lt;&#x2F;code&gt; as the &lt;code&gt;timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The rationale for this is to guarantee that the tokens &lt;code&gt;vested&lt;&#x2F;code&gt; and tokens &lt;code&gt;vesting&lt;&#x2F;code&gt; are always in sync. The intent is that the vesting curves created are deterministic across the &lt;code&gt;vestingPeriod&lt;&#x2F;code&gt;. This creates useful opportunities for integration with these NFTs. For example: A vesting schedule can be iterated through and a vesting curve could be visualized, either on-chain or off-chain.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;vestedPayout&lt;&#x2F;code&gt; vs &lt;code&gt;claimedPayout&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;claimablePayout&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vestedPayout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; claimedPayout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; claimablePayout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; lockedPayout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vestedPayout(uint256 tokenId)&lt;&#x2F;code&gt; provides the total amount of payout tokens which have &lt;strong&gt;vested&lt;&#x2F;strong&gt; &lt;em&gt;including &lt;code&gt;claimedPayout(uint256 tokenId)&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claimedPayout(uint256 tokenId)&lt;&#x2F;code&gt; provides the total amount of payout tokens which have been unlocked at the current &lt;code&gt;timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claimablePayout(uint256 tokenId)&lt;&#x2F;code&gt; provides the amount of payout tokens which can be unlocked at the current &lt;code&gt;timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The rationale for providing three functions is to support a number of features:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The return of &lt;code&gt;vestedPayout(uint256 tokenId)&lt;&#x2F;code&gt; will always match the return of &lt;code&gt;vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)&lt;&#x2F;code&gt; with &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; as the &lt;code&gt;timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claimablePayout(uint256 tokenId)&lt;&#x2F;code&gt; can be used to easily see the current payout unlock amount and allow for unlock cliffs by returning zero until a &lt;code&gt;timestamp&lt;&#x2F;code&gt; has been passed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claimedPayout(uint256 tokenId)&lt;&#x2F;code&gt; is helpful to see tokens unlocked from an NFT and it is also necessary for the calculation of vested-but-locked payout tokens: &lt;code&gt;vestedPayout - claimedPayout - claimablePayout = lockedPayout&lt;&#x2F;code&gt;. This would depend on how the vesting curves are configured by the an implementation of this standard.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;code&gt;vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)&lt;&#x2F;code&gt; provides functionality to iterate through the &lt;code&gt;vestingPeriod(uint256 tokenId)&lt;&#x2F;code&gt; and provide a visual of the release curve. The intent is that release curves are created which makes &lt;code&gt;vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)&lt;&#x2F;code&gt; deterministic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;timestamps&quot;&gt;Timestamps&lt;&#x2F;h3&gt;
&lt;p&gt;Generally in Solidity development it is advised against using &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; as a state dependent variable as the timestamp of a block can be manipulated by a miner. The choice to use a &lt;code&gt;timestamp&lt;&#x2F;code&gt; over a &lt;code&gt;block&lt;&#x2F;code&gt; is to allow the interface to work across multiple &lt;strong&gt;Ethereum Virtual Machine&lt;&#x2F;strong&gt; (EVM) compatible networks which generally have different block times. Block proposal with a significantly fabricated timestamp will generally be dropped by all node implementations which makes the window for abuse negligible.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;timestamp&lt;&#x2F;code&gt; makes cross chain integration easy, but internally, the reference implementation keeps track of the token payout per Vesting NFT to ensure that excess tokens allotted by the vesting terms cannot be claimed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;limitation-of-scope&quot;&gt;Limitation of Scope&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Historical claims&lt;&#x2F;strong&gt;: While historical vesting schedules can be determined on-chain with &lt;code&gt;vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)&lt;&#x2F;code&gt;, historical claims would need to be calculated through historical transaction data. Most likely querying for &lt;code&gt;PayoutClaimed&lt;&#x2F;code&gt; events to build a historical graph.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;extension-possibilities&quot;&gt;Extension Possibilities&lt;&#x2F;h3&gt;
&lt;p&gt;These feature are not supported by the standard as is, but the standard could be extended to support these more advanced features.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Custom Vesting Curves&lt;&#x2F;strong&gt;: This standard intends on returning deterministic &lt;code&gt;vesting&lt;&#x2F;code&gt; values given NFT &lt;code&gt;tokenId&lt;&#x2F;code&gt; and a &lt;strong&gt;timestamp&lt;&#x2F;strong&gt; as inputs. This is intentional as it provides for flexibility in how the vesting curves work under the hood which doesn&#x27;t constrain projects who intend on building a complex smart contract vesting architecture.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;NFT Rentals&lt;&#x2F;strong&gt;: Further complex DeFi tools can be created if vesting NFTs could be rented.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is done intentionally to keep the base standard simple. These features can and likely will be added through extensions of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;The Vesting NFT standard is meant to be fully backwards compatible with any current &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; integrations and marketplaces.&lt;&#x2F;li&gt;
&lt;li&gt;The Vesting NFT standard also supports &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface detection for detecting &lt;code&gt;EIP-721&lt;&#x2F;code&gt; compatibility, as well as Vesting NFT compatibility.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The reference vesting NFT repository includes tests written in Hardhat.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation of this EIP can be found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5725&#x2F;assets&#x2F;README&#x2F;&quot;&gt;ERC-5725 assets&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;timestamps&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Vesting schedules are based on timestamps. As such, it&#x27;s important to keep track of the number of tokens which have been claimed and to not give out more tokens than allotted for a specific Vesting NFT.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vestedPayoutAtTime(tokenId, type(uint256).max)&lt;&#x2F;code&gt;, for example, must return the total payout for a given &lt;code&gt;tokenId&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;approvals&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;When an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; approval is made on a Vesting NFT, the operator would have the rights to transfer the Vesting NFT to themselves and then claim the vested tokens.&lt;&#x2F;li&gt;
&lt;li&gt;When a ERC-5725 approval is made on a Vesting NFT, the operator would have the rights to claim the vested tokens, but not transfer the NFT away from the owner.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multiverse NFTs</title>
        <published>2022-09-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gaurang Torvekar</name><uri>https://github.com/gaurangtorvekar</uri>
	</author>
	
	<author>
		<name>Khemraj Adhawade</name><uri>https://github.com/akhemraj</uri>
	</author>
	
	<author>
		<name>Nikhil Asrani</name><uri>https://github.com/nikhilasrani</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5606/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5606-multiverse-nfts-for-digital-asset-interoperability/10698" />
        

        <id>https://wg-eips.ritovision.com/5606/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5606"
            label="ERC-5606" />
        

        
        

        
        <summary type="html">A universal representation of multiple related NFTs as a single digital asset across various platforms</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5606/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines a minimal interface to create a multiverse NFT standard for digital assets such as wearables and in-game items that, in turn, index the delegate NFTs on each platform where this asset exists. These platforms could be metaverses, play-to-earn games or NFT marketplaces. This proposal depends on and extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;. The standard also allows for the ‘bundling’ and ‘unbundling’ of these delegate NFTs within the multiverse NFT so holders can trade them individually or as a bundle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Several metaverses and blockchain games (&quot;platforms&quot;) exist that use NFT standards such as ERC-721 and ERC-1155 for creating in-universe assets like avatar wearables, in-game items including weapons, shields, potions and much more. The biggest shortcoming while using these standards is that there is no interoperability between these platforms. As a publisher, you must publish the same digital asset (for example, a shirt) on various platforms as separate ERC-721 or ERC-1155 tokens. Moreover, there is no relationship between these, although they represent the same digital asset in reality. Hence, it is very difficult to prove the scarcity of these items on-chain.&lt;&#x2F;p&gt;
&lt;p&gt;Since their inception, NFTs were meant to be interoperable and prove the scarcity of digital assets. Although NFTs can arguably prove the scarcity of items, the interoperability aspect hasn’t been addressed yet. Creating a multiverse NFT standard that allows for indexing and ownership of a digital asset across various platforms would be the first step towards interoperability and true ownership across platforms.&lt;&#x2F;p&gt;
&lt;p&gt;In the web3 ecosystem, NFTs have evolved to represent multiple types of unique and non-fungible assets. One type of asset includes a set of NFTs related to one another. For instance, if a brand releases a new sneaker across various metaverses, it would be minted as a separate NFT on each platform. However, it is, in reality, the same sneaker.
There is a need to represent the relationship and transferability of these types of NFTs as metaverses and blockchain games gain more mainstream adoption. The ecosystem needs a better framework to address this issue rather than relying on the application level. This framework should define the relationship between these assets and the nature of their association. There is more value in the combined recognition, use and transferability of these individual NFTs as a bundle rather than their selves.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;A multiverse NFT contract represents a digital asset across multiple platforms. This contract can own one or more delegate NFT tokens of the digital asset on the various platforms through bundling or unbundling.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&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;* @dev Interface of the Multiverse NFT standard as defined in the EIP.&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;interface IMultiverseNFT {&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev struct to store delegate token details&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;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   struct DelegateData {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       address contractAddress;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       uint256 tokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       uint256 quantity;&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&gt;   &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev Emitted when one or more new delegate NFTs are added to a Multiverse NFT&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;   event Bundled(uint256 multiverseTokenID, DelegateData[] delegateData, address ownerAddress);&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;&#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;    * @dev Emitted when one or more delegate NFTs are removed from a Multiverse NFT&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;   event Unbundled(uint256 multiverseTokenID, DelegateData[] delegateData);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev Accepts the tokenId of the Multiverse NFT and returns an array of delegate token data&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;   function delegateTokens(uint256 multiverseTokenID) external view returns (DelegateData[] memory);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev Removes one or more delegate NFTs from a Multiverse NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * This function accepts the delegate NFT details and transfers those NFTs out of the Multiverse NFT contract to the owner&amp;#39;s wallet&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;   function unbundle(DelegateData[] memory delegateData, uint256 multiverseTokenID) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev Adds one or more delegate NFTs to a Multiverse NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * This function accepts the delegate NFT details and transfers those NFTs to the Multiverse NFT contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * Need to ensure that approval is given to this Multiverse NFT contract for the delegate NFTs so that they can be transferred programmatically&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;   function bundle(DelegateData[] memory delegateData, uint256 multiverseTokenID) external;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * @dev Initialises a new bundle, mints a Multiverse NFT and assigns it to msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * Returns the token ID of a new Multiverse NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    * Note - When a new Multiverse NFT is initialised, it is empty; it does not contain any delegate NFTs&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;   function initBundle(DelegateData[] memory delegateData) external;&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;Any dapp implementing this standard would initialise a bundle by calling the function &lt;code&gt;initBundle&lt;&#x2F;code&gt;. This mints a new multiverse NFT and assigns it to msg.sender. While creating a bundle, the delegate token contract addresses and the token IDs are set during the initialisation and cannot be changed after that. This avoids unintended edge cases where non-related NFTs could be bundled together by mistake.&lt;&#x2F;p&gt;
&lt;p&gt;Once a bundle is initialised, the delegate NFT tokens can then be transferred to this Multiverse NFT contract by calling the function &lt;code&gt;bundle&lt;&#x2F;code&gt; and passing the token ID of the multiverse NFT. It is essential for a dapp to get the delegate NFTs ‘approved’ from the owner to this Multiverse NFT contract before calling the bundle function. After that, the Multiverse NFT owns one or more versions of this digital asset across the various platforms.&lt;&#x2F;p&gt;
&lt;p&gt;If the owner of the multiverse NFT wants to sell or use the individual delegate NFTs across any of the platforms, they can do so by calling the function &lt;code&gt;unbundle&lt;&#x2F;code&gt;. This function transfers the particular delegate NFT token(s) to msg.sender (only if &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the owner of the multiverse NFT).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;delegateData&lt;&#x2F;code&gt; struct contains information about the delegate NFT tokens on each platform. It contains variables such as &lt;code&gt;contractAddress&lt;&#x2F;code&gt;, &lt;code&gt;tokenId&lt;&#x2F;code&gt;, &lt;code&gt;quantity&lt;&#x2F;code&gt; to differentiate the NFTs. These NFTs could be following either the ERC-721 standard or the ERC-1155 standard.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;bundle&lt;&#x2F;code&gt; and &lt;code&gt;unbundle&lt;&#x2F;code&gt; functions accept an array of DelegateData struct because of the need to cater to partial bundling and unbundling. For instance, a user could initialise a bundle with three delegate NFTs, but they should be able to bundle and unbundle less than three at any time. They can never bundle or unbundle more than three. They also need the individual token IDs of the delegate NFTs to bundle and unbundle selectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully compatible with ERC-721 and ERC-1155. Third-party applications that don’t support this EIP will still be able to use the original NFT standards without any problems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5606&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;MultiverseNFT.sol&quot;&gt;MultiverseNFT.sol&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The bundle function involves calling an external contract(s). So reentrancy prevention measures should be applied while implementing this function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Digital Receipt Non-Fungible Tokens</title>
        <published>2022-09-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Sean Darcy</name><uri>https://github.com/darcys22</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5570/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/idea-standard-digital-receipts-using-erc-721/9908" />
        

        <id>https://wg-eips.ritovision.com/5570/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5570"
            label="ERC-5570" />
        

        
        

        
        <summary type="html">Non-Fungible Tokens as digital receipts for physical purchases, where the metadata represents a JSON receipt</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5570/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC proposes a standard schema for digital receipts of transactions. Digital Receipt Non-Fungible Tokens are issued by a vendor when a customer makes a purchase from their store and contains transaction details necessary for record keeping. Digital Receipt Non-Fungible Tokens extend &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; which allows for the management and ownership of unique tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Purchases from online retailers include a receipt that is emailed and&#x2F;or physically provided to the customer. These receipts are critical for many reasons but are provided in an analogue form which is difficult to parse by financial systems. Digital receipts have never gained traction dispite the fact that point of sales systems are already digital and the customers often want this information in their own digital systems. So we are left with a redundant Digital -&amp;gt; Analogue -&amp;gt; Digital process which requires unnecessary data entry or the use of clunky receipt-scanning applications.&lt;&#x2F;p&gt;
&lt;p&gt;Digital receipts are relatively simple and can be specified with a schema that can be parsed into JSON or other structured formats. In addition we can prove the receipts validity by digitally signing the receipt using the vendors private keys.&lt;&#x2F;p&gt;
&lt;p&gt;As Ethereum scales tooling will need to be developed to provide end users with features (such as receipts) already available to fiat transactions. NFTs provide a unique opportunity to link an on chain purchase with its transaction details directly through the transaction state update. If we conceptually think of a transaction as funds provided to one participant and goods provided to another, then our real life state includes two sides of a transaction, 1) Funds changing ownership and 2) goods changing ownership. NFT receipts are first class citizens of a transaction reflecting the goods changing ownership as part of the transaction state. They will bring our on chain transaction state in line with the changes happening in the real world.&lt;&#x2F;p&gt;
&lt;p&gt;The convenience of a direct link to the transaction receipt via the transaction state is significant, other methods of distributing receipts either off chain or through smart contracts separate to the initial transaction lose this link and force the end user to manually locate the transaction details when needed.
The benefit can be demonstrated by comparing a wallet that allows a user to click through a transaction to its receipt (available immediately after purchase without any further action) verses a user needing to search through a datastore to locate a receipt for a transaction that they can see in their wallet history.&lt;&#x2F;p&gt;
&lt;p&gt;Digital receipt as NFTs can also conceptually include other important information such as item serial numbers and delivery tracking etc.&lt;&#x2F;p&gt;
&lt;p&gt;One of the major roadblocks to fully automating our finance world has been the difficulty in tracking transaction details. Human beings physically tracking paper receipts is archaic and NFTs on the blockchain provide a pathway for these systems to be significantly improved.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Transaction Flow:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A customer purchases an item from an online retailer, checking out leads the customer to an option to mint a NFT.&lt;&#x2F;li&gt;
&lt;li&gt;The smart contract provides the user with a Digital Receipt Non-Fungible Token.&lt;&#x2F;li&gt;
&lt;li&gt;When fulfilling the order, the retailer will upload the digital receipt specified in in the JSON schema below as the metadata to the previously minted NFT.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;digital-receipt-json-schema&quot;&gt;Digital Receipt JSON Schema&lt;&#x2F;h3&gt;
&lt;p&gt;The JSON schema is composed of 2 parts. The root schema contains high level details of the receipt (for example Date and Vendor) and another schema for the optionally recurring line items contained in the receipt.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;root-schema&quot;&gt;Root Schema&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;receipt.json#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Receipt Schema for Digital Receipt Non-Fungible Tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the token as a digital receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Brief description of a digital receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Details of the receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vendor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unique ID for the receipt generated by the vendor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Date Receipt Issued&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;vendor&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Vendor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Details of the entity issuing the receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name of the vendor. E.g. Acme Corp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logo&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Logo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URL of the issuer&amp;#39;s logo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;List of strings comprising the address of the issuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;minItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URL of the issuer&amp;#39;s website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contact&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contact Details&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Details of the person to contact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name of the contact person&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;position&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Position&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Position &#x2F; Role of the contact person&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;tel&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Telephone Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Telephone number of the contact person&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;email&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Email&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Email of the contact person&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;email&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;List of strings comprising the address of the contact person&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;minItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Items included into the receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;minItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uniqueItems&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;$ref&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;item.json#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;comments&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Comments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Any messages&#x2F;comments the issuer wishes to convey to the customer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Viewable&#x2F;Printable Image of the Digital Receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Digital signature by the vendor of receipts data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;extra&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Extra&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Extra information about the business&#x2F;receipt as needed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h4 id=&quot;line-items-schema&quot;&gt;Line Items Schema&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;item.json#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;quantity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unique identifier of the goods or service&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Title of the goods or service&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Description of the goods or service&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Link&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URL link to the web page for the product or sevice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URL link or hash to an external contract for this product or service&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;serial_number&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Serial Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Serial number of the item&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Supply Date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The date the goods or service were provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unit Price&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unit Price per item (excluding tax)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;tax&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Amount of tax charged for unit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name of Tax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GST&#x2F;PST etc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rate&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tax Rate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tax rate as a percentage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tax Amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Total amount of tax charged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;quantity&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Quantity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Number of units&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The schema introduced complies with ERC-721&#x27;s metadata extension, conveniently allowing previous tools for viewing NFTs to show our receipts. The new property &quot;receipt&quot; contains our newly provided receipt structure and the signature property optionally allows the vendor to digitally sign the receipt structure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of ERC-721. It is compatible with both optional extensions, Metadata and Enumerable, mentioned in ERC-721.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The data stored in the digital receipt includes various types of personally identifying information (PII), such as the vendor&#x27;s name, contact details, and the items purchased. PII is sensitive information that can be used to identify, locate, or contact an individual. Protecting the privacy of the customer is of utmost importance, as unauthorized access to PII can lead to identity theft, fraud, or other malicious activities.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure the privacy of the customer, it is crucial to encrypt the PII contained within the digital receipt. By encrypting the PII, only authorized parties with the appropriate decryption keys can access and read the information stored in the digital receipt. This ensures that the customer&#x27;s privacy is maintained, and their data is protected from potential misuse.&lt;&#x2F;p&gt;
&lt;p&gt;While encrypting PII is essential, it is important to note that defining a specific encryption standard is beyond the scope of this ERC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Refundable Tokens</title>
        <published>2022-08-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>elie222</name><uri>https://github.com/elie222</uri>
	</author>
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5507/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5507-refundable-nfts/10451" />
        

        <id>https://wg-eips.ritovision.com/5507/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5507"
            label="ERC-5507" />
        

        
        

        
        <summary type="html">Adds refund functionality to ERC-20, ERC-721, and ERC-1155 tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5507/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC adds refund functionality for initial token offerings to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;. Funds are held in escrow until a predetermined time before they are claimable. Until that predetermined time passes, users can receive a refund for tokens they have purchased.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The NFT and token spaces lack accountability. For the health of the ecosystem as a whole, better mechanisms to prevent rugpulls from happening are needed. Offering refunds provides greater protection for buyers and increases legitimacy for creators.&lt;&#x2F;p&gt;
&lt;p&gt;A standard interface for this particular use case allows for certain benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Greater Compliance with EU &quot;Distance Selling Regulations,&quot; which require a 14-day refund period for goods (such as tokens) purchased online&lt;&#x2F;li&gt;
&lt;li&gt;Interoperability with various NFT-related applications, such as portfolio browsers, and marketplaces
&lt;ul&gt;
&lt;li&gt;NFT marketplaces could place a badge indicating that the NFT is still refundable on listings, and offer to refund NFTs instead of listing them on the marketplace&lt;&#x2F;li&gt;
&lt;li&gt;DExes could offer to refund tokens if doing so would give a higher yield&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Better wallet confirmation dialogs
&lt;ul&gt;
&lt;li&gt;Wallets can better inform the user of the action that is being taken (tokens being refunded), similar to how transfers often have their own unique dialog&lt;&#x2F;li&gt;
&lt;li&gt;DAOs can better display the functionality of smart proposals that include refunding tokens&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;All implementations MUST use and follow the directions of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-20-refund-extension&quot;&gt;ERC-20 Refund Extension&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Refundable ERC-20 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The ERC-165 identifier of this interface is `0xf0ca2917`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20Refund&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refund`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of token (in terms of the indivisible unit) that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundFrom`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The account that sent the refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of token (in terms of the indivisible unit) that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active, refunds the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has the token, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `amount` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active and the sender has sufficient approval, refund the tokens and send the ether to the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has the token, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 The ether goes to msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The user from which to refund the assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `amount` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the refund price&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The amount of ether (in wei) that would be refunded for a single token unit (10**decimals indivisible units)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the first block for which the refund is not active&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The first block where the token cannot be refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundDeadlineOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-721-refund-extension&quot;&gt;ERC-721 Refund Extension&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Refundable ERC-721 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The ERC-165 identifier of this interface is `0xe97f3c83`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Refund&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* , &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC165&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refund`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundFrom`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The account that sent the refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active for the given `tokenId`, refunds the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has the token, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active and the sender has sufficient approval, refund the token and send the ether to the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has the token, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 The ether goes to msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The user from which to refund the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the refund price of the specific `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The amount of ether (in wei) that would be refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the first block for which the refund is not active for a given `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The first block where token cannot be refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundDeadlineOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;optional-erc-721-batch-refund-extension&quot;&gt;Optional ERC-721 Batch Refund Extension&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0;&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC721Refund.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Batch Refundable ERC-721 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The ERC-165 identifier of this interface is ``&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721BatchRefund&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Refund&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when one or more tokens are batch refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundBatch`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenIds` that were refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;This&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; be&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; indexed&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when one or more tokens are batch refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundFromBatch`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The account that sent the refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundFromBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           As long as the refund is active for the given `tokenIds`, refunds the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Make sure to check that the user has the tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   These must either succeed or fail together; there are no partial refunds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId`s to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           As long as the refund is active for the given `tokenIds` and the sender has sufficient approval, refund the tokens and send the ether to the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Make sure to check that the user has the tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   The ether goes to msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   These must either succeed or fail together; there are no partial refunds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The user from which to refund the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId`s to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundFromBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-1155-refund-extension&quot;&gt;ERC-1155 Refund Extension&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Refundable ERC-1155 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The ERC-165 identifier of this interface is `0x94029f5c`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155Refund&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* , &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC165&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refund`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account that requested a refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when a token is refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundFrom`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The account that sent the refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active for the given `tokenId`, refunds the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has enough tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The amount of `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         As long as the refund is active and the sender has sufficient approval, refund the tokens and send the ether to the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Make sure to check that the user has enough tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 The ether goes to msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The user from which to refund the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The amount of `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the refund price of the specific `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The amount of ether (in wei) that would be refunded for a single token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _wei&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets the first block for which the refund is not active for a given `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenId` to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The first block where the token cannot be refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundDeadlineOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;optional-erc-1155-batch-refund-extension&quot;&gt;Optional ERC-1155 Batch Refund Extension&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0;&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC1155Refund.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Batch Refundable ERC-1155 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The ERC-165 identifier of this interface is ``&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155BatchRefund&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155Refund&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when one or more tokens are batch refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundBatch`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account that requested a refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenIds` that were refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The amount of each `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;This&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; be&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amounts&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           Emitted when one or more tokens are batch refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Emitted by `refundFromBatch`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The account that sent the refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The account whose assets are refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The `tokenIds` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  _amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The amount of each `tokenId` that was refunded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RefundFromBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;This&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; may&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; be&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amounts&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           As long as the refund is active for the given `tokenIds`, refunds the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Make sure to check that the user has enough tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   These must either succeed or fail together; there are no partial refunds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId`s to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of each `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           As long as the refund is active for the given `tokenIds` and the sender has sufficient approval, refund the tokens and send the ether to the sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;              Make sure to check that the user has the tokens, and be aware of potential re-entrancy vectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   The ether goes to msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                   These must either succeed or fail together; there are no partial refunds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The user from which to refund the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The `tokenId`s to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The amount of each `tokenId` to refund&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; refundFromBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;refundDeadlineOf&lt;&#x2F;code&gt; uses blocks instead of timestamps, as timestamps are less reliable than block numbers.&lt;&#x2F;p&gt;
&lt;p&gt;The function names of &lt;code&gt;refund&lt;&#x2F;code&gt;, &lt;code&gt;refundOf&lt;&#x2F;code&gt;, and &lt;code&gt;refundDeadlineOf&lt;&#x2F;code&gt; were chosen to fit the naming style of ERC-20, ERC-721, and ERC-1155.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; is required as introspection by DApps would be made significantly harder if it were not.&lt;&#x2F;p&gt;
&lt;p&gt;Custom ERC-20 tokens are not supported, as it needlessly increases complexity, and the &lt;code&gt;refundFrom&lt;&#x2F;code&gt; function allows for this functionality when combined with a DEx.&lt;&#x2F;p&gt;
&lt;p&gt;Batch refunds are optional, as account abstraction would make atomic operations like these significantly easier. However, they might still reduce gas costs if properly implemented.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There is a potential re-entrancy risk with the &lt;code&gt;refund&lt;&#x2F;code&gt; function. Make sure to perform the ether transfer &lt;strong&gt;after&lt;&#x2F;strong&gt; the tokens are destroyed (i.e. obey the checks, effects, interactions pattern).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Consensual Soulbound Tokens</title>
        <published>2022-08-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Buzz Cai</name><uri>https://github.com/buzzcai</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5484/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5484-consensual-soulbound-tokens/10424" />
        

        <id>https://wg-eips.ritovision.com/5484/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5484"
            label="ERC-5484" />
        

        
        

        
        <summary type="html">Interface for special NFTs with immutable ownership and pre-determined immutable burn authorization</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5484/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines an interface extending &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; to create soulbound tokens. Before issuance, both parties (the issuer and the receiver), have to agree on who has the authorization to burn this token. Burn authorization is immutable after declaration. After its issuance, a soulbound token can&#x27;t be transferred, but can be burned based on a predetermined immutable burn authorization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The idea of soulbound tokens has gathered significant attention since its publishing. Without a standard interface, however, soulbound tokens are incompatible. It is hard to develop universal services targeting at soulbound tokens without minimal consensus on the implementation of the tokens.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP envisions soulbound tokens as specialized NFTs that will play the roles of credentials, credit records, loan histories, memberships, and many more. In order to provide the flexibility in these scenarios, soulbound tokens must have an application-specific burn authorization and a way to distinguish themselves from regular EIP-721 tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The token MUST implement the following interfaces:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;’s &lt;code&gt;ERC165&lt;&#x2F;code&gt; (&lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;’s &lt;code&gt;ERC721&lt;&#x2F;code&gt; (&lt;code&gt;0x80ac58cd&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;burnAuth&lt;&#x2F;code&gt; SHALL be presented to receiver before issuance.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;burnAuth&lt;&#x2F;code&gt; SHALL be Immutable after issuance.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;burnAuth&lt;&#x2F;code&gt; SHALL be the sole factor that determines which party has the rights to burn token.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The issuer SHALL present token metadata to the receiver and acquire receiver&#x27;s signature before issuance.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The issuer SHALL NOT change metadata after issuance.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&#x2F;&#x2F;&#x2F; Note: the EIP-165 identifier for this interface is 0x0489b56f&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5484&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A guideline to standardlize burn-authorization&amp;#39;s number coding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BurnAuth&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        IssuerOnly&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        OwnerOnly&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Both&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        Neither&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when a soulbound token is issued.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emit is an add-on to nft&amp;#39;s transfer emit in order to distinguish sbt &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; from vanilla nft while providing backward compatibility.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The issuer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The receiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The id of the issued token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Issued&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-variable&quot;&gt;        BurnAuth&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; burnAuth&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; provides burn authorization of the token id.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unassigned tokenIds are invalid, and queries do throw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burnAuth&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;BurnAuth&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;soulbound-token-sbts-as-an-extension-to-eip-721&quot;&gt;Soulbound Token (SBTs) as an extension to EIP-721&lt;&#x2F;h3&gt;
&lt;p&gt;We believe that soulbound token serves as a specialized subset of the existing EIP-721 tokens. The advantage of such design is seamless compatibility of soulbound token with existing NFT services. Service providers can treat SBTs like NFTs and do not need to make drastic changes to their existing codebase.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;non-transferable&quot;&gt;Non-Transferable&lt;&#x2F;h3&gt;
&lt;p&gt;One problem with current soulbound token implementations that extend from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; is that all transfer implementations throw errors. A much cleaner approach would be for transfer functions to still throw, but also enable third parties to check beforehand if the contract implements the soulbound interface to avoid calling transfer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;burn-authorization&quot;&gt;Burn Authorization&lt;&#x2F;h3&gt;
&lt;p&gt;We want maximum freedom when it comes to interface usage. A flexible and predetermined rule to burn is crucial. Here are some sample scenarios for different burn authorizations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IssuerOnly&lt;&#x2F;code&gt;: Loan record&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ReceiverOnly&lt;&#x2F;code&gt;: Paid membership&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Both&lt;&#x2F;code&gt;: Credentials&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Neither&lt;&#x2F;code&gt;: Credit history&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Burn authorization is tied to specific tokens and immutable after issuance. It is therefore important to inform the receiver and gain receiver&#x27;s consent before the token is issued.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;issued-event&quot;&gt;Issued Event&lt;&#x2F;h3&gt;
&lt;p&gt;On issuing, an &lt;code&gt;Issued&lt;&#x2F;code&gt; event will be emitted alongside &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;Transfer&lt;&#x2F;code&gt; event. This design keeps backward compatibility while giving clear signals to thrid-parties that this is a soulBound token issuance event.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-rotations&quot;&gt;Key Rotations&lt;&#x2F;h3&gt;
&lt;p&gt;A concern Ethereum users have is that soulbound tokens having immutable ownership discourage key rotations. This is a valid concern. Having a burnable soulbound token, however, makes key rotations achievable. The owner of the soulbound token, when in need of key rotations, can inform the issuer of the token. Then the party with burn authorization can burn the token while the issuer can issue a replica to the new address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>NFT Hyperlink Extension</title>
        <published>2022-08-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>IronMan_CH</name><uri>https://github.com/coderfengyun</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5489/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5489-nft-hyperlink-extension/10431" />
        

        <id>https://wg-eips.ritovision.com/5489/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5489"
            label="ERC-5489" />
        

        
        

        
        <summary type="html">NFT Hyperlink Extension embeds hyperlinks onto NFTs, allowing users to click any hNFT and be transported to any url set by the owner.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5489/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a new extension for NFTs (non-fungible token, aka &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;): nft-hyperlink-extention (hNFT), embedding NFTs with hyperlinks, referred to as “hNFTs”. As owners of hNFTs, users may authorize a URL slot to a specific address which can be either an externally-owned account (EOA) or a contract address and hNFT owners are entitled to revoke that authorization at any time. The address which has slot authorization can manage the URL of that slot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;As NFTs attract more attention, they have the potential to become the primary medium of Web3. Currently, end users can’t attach rich texts, videos, or images to NFTs, and there’s no way to render these rich-content attachments. Many industries eagerly look forward to this kind of rich-content attachment ability. Attaching, editing, and displaying highly customized information can usefully be standardized.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP uses hyperlinks as the aforementioned form of “highly customized attachment on NFT”, and also specifies how to attach, edit, and display these attachments on NFTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;ierc5489&quot;&gt;&lt;code&gt;IERC5489&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5489&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this event emits when the slot on `tokenId` is authorzized to `slotManagerAddr`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SlotAuthorizationCreated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this event emits when the authorization on slot `slotManagerAddr` of token `tokenId` is revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * So, the corresponding DApp can handle this to stop on-going incentives or rights&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SlotAuthorizationRevoked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this event emits when the uri on slot `slotManagerAddr` of token `tokenId` has been updated to `uri`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SlotUriUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uri&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Authorize a hyperlink slot on `tokenId` to address `slotManagerAddr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Indeed slot is an entry in a map whose key is address `slotManagerAddr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Only the address `slotManagerAddr` can manage the specific slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This method will emit SlotAuthorizationCreated event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeSlotTo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Revoke the authorization of the slot indicated by `slotManagerAddr` on token `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This method will emit SlotAuthorizationRevoked event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeAuthorization&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Revoke all authorizations of slot on token `tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This method will emit SlotAuthorizationRevoked event for each slot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeAllAuthorizations&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Set uri for a slot on a token, which is indicated by `tokenId` and `slotManagerAddr`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Only the address with authorization through {authorizeSlotTo} can manipulate this slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This method will emit SlotUriUpdated event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setSlotUri&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newUri&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `tokenId` is not a valid NFT. URIs are defined in RFC 3986.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The URI MUST point to a JSON file that conforms to the &amp;quot;EIP5489 Metadata JSON schema&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * returns the latest uri of an slot on a token, which is indicated by `tokenId`, `slotManagerAddr`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getSlotUri&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slotManagerAddr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;authorizeSlotTo(uint256 tokenId, address slotManagerAddr)&lt;&#x2F;code&gt; function MAY be implemented as public or external.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;revokeAuthorization(uint256 tokenId, address slotManagerAddr)&lt;&#x2F;code&gt; function MAY be implemented as public or external.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;revokeAllAuthorizations(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as public or external.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;setSlotUri(uint256 tokenId, string calldata newUri)&lt;&#x2F;code&gt; function MAY be implemented as public or external.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;getSlotUri(uint256 tokenId, address slotManagerAddr)&lt;&#x2F;code&gt; function MAY be implemented as pure or view.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;SlotAuthorizationCreated&lt;&#x2F;code&gt; event MUST be emitted when a slot is authorized to an address.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;SlotAuthorizationRevoked&lt;&#x2F;code&gt; event MUST be emitted when a slot authorization is revoked.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;SlotUriUpdated&lt;&#x2F;code&gt; event MUSt be emitted when a slot&#x27;s URI is changed.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportInterface&lt;&#x2F;code&gt; method MUST return true when called with &lt;code&gt;0x8f65987b&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;authentication&quot;&gt;Authentication&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;authorizeSlotTo&lt;&#x2F;code&gt;, &lt;code&gt;revokeAuthorization&lt;&#x2F;code&gt;, and &lt;code&gt;revokeAllAuthorizations&lt;&#x2F;code&gt; functions are authenticated if and only if the message sender is the owner of the token.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;metadata-json-schema&quot;&gt;Metadata JSON schema&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;AD Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;icon&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the slot&amp;#39;s occupier. Consider making any images at a width between 48 and 1080 pixels and aspect ration between 1.91:1 and 4:5 inclusive. Suggest to show this as an thumbnail of the target resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A paragraph which briefly introduce what is the target resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to target resource, sugguest to follow 30X status code to support more redirections, the mime type and content rely on user&amp;#39;s setting&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;extends-nft-with-hyperlinks&quot;&gt;Extends NFT with hyperlinks&lt;&#x2F;h3&gt;
&lt;p&gt;URIs are used to represent the value of slots to ensure enough flexibility to deal with different use cases.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;authorize-slot-to-address&quot;&gt;Authorize slot to address&lt;&#x2F;h3&gt;
&lt;p&gt;We use addresses to represent the key of slots to ensure enough flexibility to deal with all use cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the specifications section, this standard can be fully EIP-721 compatible by adding an extension function set.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, new functions introduced in this standard have many similarities with the existing functions in EIP-721. This allows developers to easily adopt the standard quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;You can find an implementation of this standard in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5489&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC5489.sol&quot;&gt;&lt;code&gt;ERC5489.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security considerations were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Refundable Fungible Token</title>
        <published>2022-08-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>StartfundInc</name><uri>https://github.com/StartfundInc</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5528/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5528-refundable-token-standard/10494" />
        

        <id>https://wg-eips.ritovision.com/5528/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5528"
            label="ERC-5528" />
        

        
        

        
        <summary type="html">Allows refunds for EIP-20 tokens by escrow smart contract</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5528/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt;. This specification defines a type of escrow service with the following flow:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The seller issues tokens.&lt;&#x2F;li&gt;
&lt;li&gt;The seller creates an escrow smart contract with detailed escrow information like contract addresses, lock period, exchange rate, additional escrow success conditions, etc.&lt;&#x2F;li&gt;
&lt;li&gt;The seller funds seller tokens to the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Buyers fund buyer tokens which are pre-defined in the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;When the escrow status meets success, the seller can withdraw buyer tokens, and buyers can withdraw seller tokens based on exchange rates.&lt;&#x2F;li&gt;
&lt;li&gt;Buyers can withdraw (or refund) their funded token if the escrow process is failed or is in the middle of the escrow process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Because of the pseudonymous nature of cryptocurrencies, there is no automatic recourse to recover funds that have already been paid.&lt;&#x2F;p&gt;
&lt;p&gt;In traditional finance, trusted escrow services solve this problem. In the world of decentralized cryptocurrency, however, it is possible to implement an escrow service without a third-party arbitrator. This standard defines an interface for smart contracts to act as an escrow service with a function where tokens are sent back to the original wallet if the escrow is not completed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;There are two types of contract for the escrow process:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Payable Contract&lt;&#x2F;em&gt;: The sellers and buyers use this token to fund the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;. This contract MUST override &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; interfaces.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;: Defines the escrow policies and holds &lt;em&gt;Payable Contract&lt;&#x2F;em&gt;&#x27;s token for a certain period. This contract does not requires override &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; interfaces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;constructor&quot;&gt;&lt;code&gt;constructor&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; demonstrates details of escrow policies as none-mutable matter in constructor implementation.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; MUST define the following policies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Seller token contract address&lt;&#x2F;li&gt;
&lt;li&gt;Buyer token contract address&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; MAY define the following policies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Escrow period&lt;&#x2F;li&gt;
&lt;li&gt;Maximum (or minimum) number of investors&lt;&#x2F;li&gt;
&lt;li&gt;Maximum (or minimum) number of tokens to fund&lt;&#x2F;li&gt;
&lt;li&gt;Exchange rates of seller&#x2F;buyer token&lt;&#x2F;li&gt;
&lt;li&gt;KYC verification of users&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;escrowfund&quot;&gt;&lt;code&gt;escrowFund&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Funds &lt;code&gt;_value&lt;&#x2F;code&gt; amount of tokens to address &lt;code&gt;_to&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_to&lt;&#x2F;code&gt; MUST be the user address.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST be the &lt;em&gt;Payable Contract&lt;&#x2F;em&gt; address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST check policy validations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the case of &lt;em&gt;Payable Contract&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The address &lt;code&gt;_to&lt;&#x2F;code&gt; MUST be the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST call the same function of the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; interface. The parameter &lt;code&gt;_to&lt;&#x2F;code&gt; MUST be &lt;code&gt;msg.sender&lt;&#x2F;code&gt; to recognize the user address in the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowFund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;escrowrefund&quot;&gt;&lt;code&gt;escrowRefund&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Refunds &lt;code&gt;_value&lt;&#x2F;code&gt; amount of tokens from address &lt;code&gt;_from&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_from&lt;&#x2F;code&gt; MUST be the user address.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST be the &lt;em&gt;Payable Contract&lt;&#x2F;em&gt; address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST check policy validations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the case of &lt;em&gt;Payable Contract&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The address &lt;code&gt;_from&lt;&#x2F;code&gt; MUST be the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST call the same function of the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; interface. The parameter &lt;code&gt;_from&lt;&#x2F;code&gt; MUST be &lt;code&gt;msg.sender&lt;&#x2F;code&gt; to recognize the user address in the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowRefund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h4 id=&quot;escrowwithdraw&quot;&gt;&lt;code&gt;escrowWithdraw&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Withdraws funds from the escrow account.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST check the escrow process is completed.&lt;&#x2F;li&gt;
&lt;li&gt;MUST send the remaining balance of seller and buyer tokens to &lt;code&gt;msg.sender&lt;&#x2F;code&gt;&#x27;s seller and buyer contract wallets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the case of &lt;em&gt;Payable Contract&lt;&#x2F;em&gt;, it is optional.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;h3 id=&quot;example-of-interface&quot;&gt;Example of interface&lt;&#x2F;h3&gt;
&lt;p&gt;This example demonstrates simple exchange of one seller and one buyer in one-to-one exchange rates.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5528&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowFund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowRefund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PayableContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5528&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;      General ERC20 implementations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; fromBalance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;fromBalance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC20: transfer amount exceeds balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        _balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fromBalance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&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&gt;        _balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowFund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; res &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;escrowFund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;res&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Fund Failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowRefund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; res &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_from&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;escrowRefund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;res&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Refund Failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EscrowContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5528&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; State&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Inited&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Running&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Closed&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BalanceData&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; _addrSeller&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; _addrBuyer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    BalanceData _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    BalanceData _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    EscrowStatus _status&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sellerContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; buyerContract&lt;&#x2F;span&gt;&lt;span&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&gt;        _addrSeller &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; sellerContract&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _addrBuyer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; buyerContract&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _status &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Inited&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowFund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _addrSeller&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_status&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;state &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Running&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;must be running state&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;            _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;            _status &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Success&lt;&#x2F;span&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;span class=&quot;z-keyword&quot;&gt;else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _addrBuyer&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_status&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;state &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Inited&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;must be init state&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;            _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;            _status &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Running&lt;&#x2F;span&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;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Invalid to address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowRefund&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_status&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;state &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Running&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;refund is only available on running state&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _addrBuyer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;invalid caller for refund&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;only buyer can refund&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;buyer fund is not enough to refund&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; escrowWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_status&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;state &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;withdraw is only available on success state&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; common &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MIN&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;common &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&gt;            _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; common&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; common&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Exchange&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addrSeller&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; common&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addrBuyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; common&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; send back the remaining balances&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;                IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addrBuyer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _fundBuyer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&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&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;                IERC5528&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addrSeller&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _fundSeller&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;amount&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _status &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Closed&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The interfaces cover the escrow operation&#x27;s refundable issue.&lt;&#x2F;p&gt;
&lt;p&gt;The suggested 3 functions (&lt;code&gt;escrowFund&lt;&#x2F;code&gt;, &lt;code&gt;escrowRefund&lt;&#x2F;code&gt; and &lt;code&gt;escrowWithdraw&lt;&#x2F;code&gt;) are based on &lt;code&gt;transfer&lt;&#x2F;code&gt; function in EIP-20.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;escrowFund&lt;&#x2F;code&gt; send tokens to the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt;. The &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; can hold the contract in the escrow process or reject tokens if the policy does not meet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;escrowRefund&lt;&#x2F;code&gt; can be invoked in the middle of the escrow process or when the escrow process fails.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;escrowWithdraw&lt;&#x2F;code&gt; allows users (sellers and buyers) to transfer tokens from the escrow account. When the escrow process completes, the seller can get the buyer&#x27;s token, and the buyers can get the seller&#x27;s token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;em&gt;Payable Contract&lt;&#x2F;em&gt; which implements this EIP is fully backward compatible with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5528&#x2F;.&#x2F;assets&#x2F;truffule-test.js&quot;&gt;Unit test example by truffle&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This test case demonstrates the following conditions for exchanging seller&#x2F;buyer tokens.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The exchange rate is one-to-one.&lt;&#x2F;li&gt;
&lt;li&gt;If the number of buyers reaches 2, the escrow process will be terminated(success).&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise (not meeting success condition yet), buyers can refund (or withdraw) their funded tokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Since the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; controls seller and buyer rights, flaws within the &lt;em&gt;Escrow Contract&lt;&#x2F;em&gt; will directly lead to unexpected behavior and potential loss of funds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC-721 NFT Authorization</title>
        <published>2022-08-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Veega Labs</name><uri>https://github.com/VeegaLabsOfficial</uri>
	</author>
	
	<author>
		<name>Sean NG</name><uri>https://github.com/ngveega</uri>
	</author>
	
	<author>
		<name>Tiger</name><uri>https://github.com/tiger0x</uri>
	</author>
	
	<author>
		<name>Fred</name><uri>https://github.com/apan826</uri>
	</author>
	
	<author>
		<name>Fov Cao</name><uri>https://github.com/fovcao</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5585/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/nft-authorization-erc721-extension/10661" />
        

        <id>https://wg-eips.ritovision.com/5585/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5585"
            label="ERC-5585" />
        

        
        

        
        <summary type="html">Allows NFT owners to authorize other users to use their NFTs.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5585/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP separates the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; NFT&#x27;s commercial usage rights from its ownership to allow for the independent management of those rights.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Most NFTs have a simplified ownership verification mechanism, with a sole owner of an NFT. Under this model, other rights, such as display, or creating derivative works or distribution, are not possible to grant, limiting the value and commercialization of NFTs. Therefore, the separation of an NFT&#x27;s ownership and user rights can enhance its commercial value.&lt;&#x2F;p&gt;
&lt;p&gt;Commercial right is a broad concept based on the copyright, including the rights of copy, display, distribution, renting, commercial use, modify, reproduce and sublicense etc.  With the development of the Metaverse, NFTs are becoming more diverse, with new use cases such as digital collections, virtual real estate, music, art, social media, and digital asset of all kinds. The copyright and authorization based on NFTs are becoming a potential business form.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5585&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UserRecord&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; rights&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get all available rights of this NFT project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; All&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the rights that can be authorized to the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getRights&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFT holder authorizes all the rights of the NFT to a user for a specified period of time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT which is authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user to whom the NFT is authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The period of time the authorization lasts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFT holder authorizes specific rights to a user for a specified period of time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user. It will throw exception when the rights are not defined by this NFT project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT which is authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user to whom the NFT is authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rights authorized to the user, such as renting, distribution or display etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The period of time the authorization lasts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user of the NFT transfers his rights to the new user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The rights of this NFT is transferred to the new user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; newUser&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferUserRights&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newUser&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFT holder extends the duration of authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user. It will throw exception when the rights are not defined by this NFT project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT which has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user to whom the NFT has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new duration of the authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; extendDuration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; duration&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFT holder updates the rights of authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT which has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user to whom the NFT has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; New rights authorized to the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateUserRights&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the authorization expired time of the specified NFT and user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the user expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user who has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; authorization expired time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getExpires&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the rights of the specified NFT and user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the rights&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user who has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; rights has been authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getUserRights&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The contract owner can update the number of users that can be authorized per NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userLimit&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of users set by operators only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateUserLimit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userLimit&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; resetAllowed flag can be updated by contract owner to control whether the authorization can be revoked or not &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; resetAllowed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; It is the boolean flag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateResetAllowed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; resetAllowed&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if the token is available for authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if tokenId is not a valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to be checked the availability&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or false whether the NFT is available for authorization or not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkAuthorizationAvailability&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Clear authorization of a specified user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user. The function  works when resetAllowed is true and it will throw exception when false  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT on which the authorization based&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The user whose authorization will be cleared&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resetUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the user of a NFT is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or the authorization expires time is updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; param tokenId The NFT on which the authorization based&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; param indexed user The user to whom the NFT authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rights authorized to the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The expires time of the authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; rights&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the number of users that can be authorized per NFT is updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; userLimit&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number of users set by operators only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateUserLimit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; userLimit&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;getRights()&lt;&#x2F;code&gt; function MAY be implemented as pure and view.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;authorizeUser(uint256 tokenId, address user, uint duration)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;authorizeUser(uint256 tokenId, address user, string[] rights; uint duration)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;transferUserRights(uint256 tokenId, address newUser)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;extendDuration(uint256 tokenId, address user, uint duration)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;updateUserRights(uint256 tokenId, address user, string[] rights)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;getExpires(uint256 tokenId, address user)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;getUserRights(uint256 tokenId, address user)&lt;&#x2F;code&gt; function MAY be implemented as pure and view.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;updateUserLimit(unit256 userLimit)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;updateResetAllowed(bool resetAllowed)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;checkAuthorizationAvailability(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;resetUser(uint256 tokenId, address user)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;authorizeUser&lt;&#x2F;code&gt; event MUST be emitted when the user of a NFT is changed or the authorization expires time is updated.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;updateUserLimit&lt;&#x2F;code&gt; event MUST be emitted when the number of users that can be authorized per NFT is updated.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;First of all, NFT contract owner can set the maximum number of authorized users to each NFT and whether the NFT owner can cancel the authorization at any time to protect the interests of the parties involved.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, there is a &lt;code&gt;resetAllowed&lt;&#x2F;code&gt; flag to control the rights between the NFT owner and the users for the contract owner. If the flag is set to true, then the NFT owner can disable usage rights of all authorized users at any time.&lt;&#x2F;p&gt;
&lt;p&gt;Thirdly, the rights within the user record struct is used to store what rights has been authorized to a user by the NFT owner, in other words, the NFT owner can authorize a user with specific rights and update it when necessary.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, this design can be seamlessly integrated with third parties. It is an extension of ERC-721, therefore it can be easily integrated into a new NFT project. Other projects can directly interact with these interfaces and functions to implement their own types of transactions. For example, an announcement platform could use this EIP to allow all NFT owners to make authorization or deauthorization at any time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; since it is an extension of it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;When the &lt;code&gt;resetAllowed&lt;&#x2F;code&gt; flag is false, which means the authorization can not be revoked by NFT owner during the period of authorization, users of the EIP need to make sure the authorization fee can be fairly assigned if the NFT was sold to a new holder.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a solution for taking reference: the authorization fee paid by the users can be held in an escrow contract for a period of time depending on the duration of the authorization. For example, if the authorization duration is 12 months and the fee in total is 10 ETH, then if the NFT is transferred after 3 months, then only 2.5 ETH would be sent and the remaining 7.5 ETH would be refunded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Stealth Addresses</title>
        <published>2022-08-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Toni Wahrstätter</name><uri>https://github.com/nerolation</uri>
	</author>
	
	<author>
		<name>Matt Solomon</name><uri>https://github.com/mds1</uri>
	</author>
	
	<author>
		<name>Ben DiFrancesco</name><uri>https://github.com/apbendi</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5564/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5566-stealth-addresses-for-smart-contract-wallets/10614" />
        

        <id>https://wg-eips.ritovision.com/5564/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5564"
            label="ERC-5564" />
        

        
        

        
        <summary type="html">Private, non-interactive transactions</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5564/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification establishes a standardized method for interacting with stealth addresses, which allow senders of transactions or transfers to non-interactively generate private accounts exclusively accessible by their recipients. Moreover, this specification enables developers to create stealth address protocols based on the foundational implementation outlined in this ERC, utilizing a singleton contract deployed at &lt;code&gt;0x55649E01B5Df198D18D95b5cc5051630cfD45564&lt;&#x2F;code&gt; to emit the necessary information for recipients. In addition to the base implementation, this ERC also outlines the first implementation of a cryptographic scheme, specifically the SECP256k1 curve.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The standardization of non-interactive stealth address generation presents the potential to significantly improve the privacy capabilities of the Ethereum network and other EVM-compatible chains by allowing recipients to remain private when receiving assets. This is accomplished through the sender generating a stealth address based on a shared secret known exclusively to the sender and recipient. The recipients alone can access the funds stored at their stealth addresses, as they are the sole possessors of the necessary private key. As a result, observers are unable to associate the recipient&#x27;s stealth address with their identity, thereby preserving the recipient&#x27;s privacy and leaving the sender as the only party privy to this information. By offering a foundational implementation in the form of a single contract that is compatible with multiple cryptographic schemes, recipients are granted a centralized location to monitor, ensuring they do not overlook any incoming transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;Definitions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A &quot;stealth meta-address&quot; is a set of one or two public keys that can be used to compute a stealth address for a given recipient.&lt;&#x2F;li&gt;
&lt;li&gt;A &quot;spending key&quot; is a private key that can be used to spend funds sent to a stealth address. A &quot;spending public key&quot; is the corresponding public key.&lt;&#x2F;li&gt;
&lt;li&gt;A &quot;viewing key&quot; is a private key that can be used to determine if funds sent to a stealth address belong to the recipient who controls the corresponding spending key. A &quot;viewing public key&quot; is the corresponding public key.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Different stealth address schemes will have different expected stealth meta-address lengths. A scheme that uses public keys of length &lt;code&gt;n&lt;&#x2F;code&gt; bytes MUST define stealth meta-addresses as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A stealth meta-address of length &lt;code&gt;n&lt;&#x2F;code&gt; uses the same stealth meta-address for the spending public key and viewing public key.&lt;&#x2F;li&gt;
&lt;li&gt;A stealth meta-address of length &lt;code&gt;2n&lt;&#x2F;code&gt; uses the first &lt;code&gt;n&lt;&#x2F;code&gt; bytes as the spending public key and the last &lt;code&gt;n&lt;&#x2F;code&gt; bytes as the viewing public key.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given a recipient&#x27;s stealth meta-address, a sender MUST be able generate a stealth address for the recipient by calling a method with the following signature:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Generates a stealth address from a stealth meta address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s stealth meta-address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ephemeral public key used to generate the stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; viewTag&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The view tag derived from the shared secret.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; generateStealthAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthMetaAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes1&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; viewTag&lt;&#x2F;span&gt;&lt;span&gt;)&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 recipient MUST be able to check if a stealth address belongs to them by calling a method with the following signature:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if funds sent to a stealth address belong to the recipient who controls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the corresponding spending key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ephemeral public key used to generate the stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; viewingKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s viewing private key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spendingPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s spending public key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if funds sent to the stealth address belong to the recipient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkStealthAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; viewingKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spendingPubKey&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&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 recipient MUST be able to compute the private key for a stealth address by calling a method with the following signature:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Computes the stealth private key for a stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The expected stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ephemeral public key used to generate the stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; viewingKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s viewing private key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spendingKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The recipient&amp;#39;s spending private key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth private key corresponding to the stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The stealth address input is not strictly necessary, but it is included so the method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; can validate that the stealth private key was generated correctly.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; computeStealthKey&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; viewingKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spendingKey&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&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 implementation of these methods is scheme-specific. The specification of a new stealth address scheme MUST specify the implementation for each of these methods. Additionally, although these function interfaces are specified in Solidity, they do not necessarily ever need to be implemented in Solidity, but any library or SDK conforming to this specification MUST implement these methods with compatible function interfaces.&lt;&#x2F;p&gt;
&lt;p&gt;A 256 bit integer (&lt;code&gt;schemeId&lt;&#x2F;code&gt;) is used to identify stealth address schemes. A mapping from the schemeId to its specification MUST be declared in the ERC that proposes to standardize a new stealth address scheme. It is RECOMMENDED that &lt;code&gt;schemeId&lt;&#x2F;code&gt;s are chosen to be monotonically incrementing integers for simplicity, but arbitrary or meaningful &lt;code&gt;schemeId&lt;&#x2F;code&gt;s may be chosen. This ERC introduces a &lt;code&gt;schemeId&lt;&#x2F;code&gt; of &lt;code&gt;1&lt;&#x2F;code&gt; with the following extensions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1&lt;&#x2F;code&gt; is the integer identifier for the scheme,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;viewTags&lt;&#x2F;code&gt; MUST be included in the announcement event and is used to reduce the parsing time for the recipients.&lt;&#x2F;li&gt;
&lt;li&gt;SECP256k1 is the algorithm for encoding a stealth meta-address (i.e. the spending public key and viewing public key) into a &lt;code&gt;bytes&lt;&#x2F;code&gt; array, and decoding it from &lt;code&gt;bytes&lt;&#x2F;code&gt; to the native key types of that scheme.&lt;&#x2F;li&gt;
&lt;li&gt;SECP256k1 with view tags will be used in &lt;code&gt;generateStealthAddress&lt;&#x2F;code&gt;, &lt;code&gt;checkStealthAddress&lt;&#x2F;code&gt;, and &lt;code&gt;computeStealthKey&lt;&#x2F;code&gt; methods.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This specification additionally defines a singleton &lt;code&gt;ERC5564Announcer&lt;&#x2F;code&gt; contract that emits events to announce when something is sent to a stealth address. This MUST be a singleton contract, with one instance per chain. The contract is specified as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for announcing when something is sent to a stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5564Announcer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when sending something to a stealth address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See the `announce` method for documentation on the parameters.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Announcement&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadata&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&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Called by integrators to emit an `Announcement` event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The integer specifying the applied stealth address scheme.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The computed stealth address for the recipient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ephemeral public key used by the sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An arbitrary field MUST include the view tag in the first byte.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Besides the view tag, the metadata can be used by the senders however they like,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; but the below guidelines are recommended:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first byte of the metadata MUST be the view tag.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - When sending&#x2F;interacting with the native token of the blockchain (cf. ETH), the metadata SHOULD be structured as follows:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     - Byte 1 MUST be the view tag, as specified above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     - Bytes 2-5 are `0xeeeeeeee`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     - Bytes 6-25 are the address 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     - Bytes 26-57 are the amount of ETH being sent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - When interacting with ERC-20&#x2F;ERC-721&#x2F;etc. tokens, the metadata SHOULD be structured as follows:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   - Byte 1 MUST be the view tag, as specified above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   - Bytes 2-5 are a function identifier. When a function selector (e.g.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     the first (left, high-order in big-endian) four bytes of the Keccak-256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     hash of the signature of the function, like Solidity and Vyper use) is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     available, it MUST be used.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   - Bytes 6-25 are the token contract address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   - Bytes 26-57 are the amount of tokens being sent&#x2F;interacted with for fungible tokens, or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     the token ID for non-fungible tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; announce&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadata&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 class=&quot;z-storage z-type&quot;&gt;    external&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 class=&quot;z-keyword&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Announcement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;schemeId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stealthAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ephemeralPubKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; metadata&lt;&#x2F;span&gt;&lt;span&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&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;h3 id=&quot;stealth-meta-address-format&quot;&gt;Stealth meta-address format&lt;&#x2F;h3&gt;
&lt;p&gt;The new address format for the stealth meta-address extends the chain specific address format by adding a &lt;code&gt;st:&lt;&#x2F;code&gt; (&lt;em&gt;stealth&lt;&#x2F;em&gt;) prefix.
Thus, a stealth meta-address on Ethereum has the following format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;st:eth:0x&amp;lt;spendingPubKey&amp;gt;&amp;lt;viewingPubKey&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Stealth meta-addresses may be managed by the user and&#x2F;or registered within a publicly available &lt;code&gt;Registry&lt;&#x2F;code&gt; contract, as delineated in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;6538&#x2F;&quot;&gt;ERC-6538&lt;&#x2F;a&gt;. This provides users with a centralized location for identifying stealth meta-addresses associated with other individuals while simultaneously enabling recipients to express their openness to engage via stealth addresses.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Notably, the address format is used only to differentiate stealth addresses from standard addresses, as the prefix is removed before performing any computations on the stealth meta-address.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;initial-implementation-of-secp256k1-with-view-tags&quot;&gt;Initial Implementation of SECP256k1 with View Tags&lt;&#x2F;h3&gt;
&lt;p&gt;This ERC provides a foundation that is not tied to any specific cryptographic system through the &lt;code&gt;IERC5564Announcer&lt;&#x2F;code&gt; contract. In addition, it introduces the first implementation of a stealth address scheme that utilizes the SECP256k1 elliptic curve and view tags. The SECP256k1 elliptic curve is defined with the equation $y^2 = x^3 + 7 \pmod{p}$, where $p = 2^{256} - 2^{32} - 977$.&lt;&#x2F;p&gt;
&lt;p&gt;The following reference is divided into three sections:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Stealth address generation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Parsing announcements&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Stealth private key derivation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Definitions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$G$ represents the generator point of the curve.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;generation-generate-stealth-address-from-stealth-meta-address&quot;&gt;Generation - Generate stealth address from stealth meta-address:&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Recipient has access to the private keys $p_{spend}$, $p_{view}$ from which public keys $P_{spend}$ and $P_{view}$ are derived.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Recipient has published a stealth meta-address that consists of the public keys $P_{spend}$ and $P_{view}$.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sender passes the stealth meta-address to the &lt;code&gt;generateStealthAddress&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;generateStealthAddress&lt;&#x2F;code&gt; function performs the following computations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Generate a random 32-byte entropy ephemeral private key $p_{ephemeral}$.&lt;&#x2F;li&gt;
&lt;li&gt;Derive the ephemeral public key $P_{ephemeral}$ from $p_{ephemeral}$.&lt;&#x2F;li&gt;
&lt;li&gt;Parse the spending and viewing public keys, $P_{spend}$ and $P_{view}$, from the stealth meta-address.&lt;&#x2F;li&gt;
&lt;li&gt;A shared secret $s$ is computed as $s = p_{ephemeral} \cdot P_{view}$.&lt;&#x2F;li&gt;
&lt;li&gt;The secret is hashed $s_{h} = \textrm{h}(s)$.&lt;&#x2F;li&gt;
&lt;li&gt;The view tag $v$ is extracted by taking the most significant byte $s_{h}[0]$,&lt;&#x2F;li&gt;
&lt;li&gt;Multiply the hashed shared secret with the generator point $S_h = s_h \cdot G$.&lt;&#x2F;li&gt;
&lt;li&gt;The recipient&#x27;s stealth public key is computed as $P_{stealth} = P_{spend} + S_h$.&lt;&#x2F;li&gt;
&lt;li&gt;The recipient&#x27;s stealth address $a_{stealth}$ is computed as $\textrm{pubkeyToAddress}(P_{stealth})$.&lt;&#x2F;li&gt;
&lt;li&gt;The function returns the stealth address $a_{stealth}$, the ephemeral public key $P_{ephemeral}$ and the view tag $v$.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;parsing-locate-one-s-own-stealth-address-es&quot;&gt;Parsing - Locate one&#x27;s own stealth address(es):&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User has access to the viewing private key $p_{view}$ and the spending public key $P_{spend}$.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;User has access to a set of &lt;code&gt;Announcement&lt;&#x2F;code&gt; events and applies the &lt;code&gt;checkStealthAddress&lt;&#x2F;code&gt; function to each of them.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;checkStealthAddress&lt;&#x2F;code&gt; function performs the following computations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Shared secret $s$ is computed by multiplying the viewing private key with the ephemeral public key of the announcement $s = p_{view}$ * $P_{ephemeral}$.&lt;&#x2F;li&gt;
&lt;li&gt;The secret is hashed $s_{h} = h(s)$.&lt;&#x2F;li&gt;
&lt;li&gt;The view tag $v$ is extracted by taking the most significant byte $s_{h}[0]$ and can be compared to the given view tag. If the view tags do not match, this &lt;code&gt;Announcement&lt;&#x2F;code&gt; is not for the user and the remaining steps can be skipped. If the view tags match, continue on.&lt;&#x2F;li&gt;
&lt;li&gt;Multiply the hashed shared secret with the generator point $S_h = s_h \cdot G$.&lt;&#x2F;li&gt;
&lt;li&gt;The stealth public key is computed as $P_{stealth} = P_{spend} + S_h$.&lt;&#x2F;li&gt;
&lt;li&gt;The derived stealth address $a_{stealth}$ is computed as $\textrm{pubkeyToAddress}(P_{stealth})$.&lt;&#x2F;li&gt;
&lt;li&gt;Return &lt;code&gt;true&lt;&#x2F;code&gt; if the stealth address of the announcement matches the derived stealth address, else return &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;private-key-derivation-generate-the-stealth-address-private-key-from-the-hashed-shared-secret-and-the-spending-private-key&quot;&gt;Private key derivation - Generate the stealth address private key from the hashed shared secret and the spending private key.&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User has access to the viewing private key $p_{view}$ and spending private key $p_{spend}$.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;User has access to a set of &lt;code&gt;Announcement&lt;&#x2F;code&gt; events for which the &lt;code&gt;checkStealthAddress&lt;&#x2F;code&gt; function returns &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;computeStealthKey&lt;&#x2F;code&gt; function performs the following computations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Shared secret $s$ is computed by multiplying the viewing private key with the ephemeral public key of the announcement $s = p_{view}$ * $P_{ephemeral}$.&lt;&#x2F;li&gt;
&lt;li&gt;The secret is hashed $s_{h} = h(s)$.&lt;&#x2F;li&gt;
&lt;li&gt;The stealth private key is computed as $p_{stealth} = p_{spend} + s_h$.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;parsing-considerations&quot;&gt;Parsing considerations&lt;&#x2F;h3&gt;
&lt;p&gt;Usually, the recipient of a stealth address transaction has to perform the following operations to check whether he was the recipient of a certain transaction:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2x ecMUL,&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;2x HASH,&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;1x ecADD,&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The view tags approach is introduced to reduce the parsing time by around 6x. Users only need to perform 1x ecMUL and 1x HASH (skipping 1x ecMUL, 1x ecADD and 1x HASH) for every parsed announcement. The 1-byte view tag length is based on the maximum required space to reliably filter non-matching announcements. With a 1-byte &lt;code&gt;viewTag&lt;&#x2F;code&gt;, the probability for users to skip the remaining computations after hashing the shared secret $h(s)$ is $255&#x2F;256$. This means that users can almost certainly skip the above three operations for any announcements that do not involve them. Since the view tag reveals one byte of the shared secret, the security margin is reduced from 128 bits to 124 bits. Notably, this only affects the privacy and not the secure generation of a stealth address.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC emerged from the need for privacy-preserving ways to transfer ownership without disclosing any information about the recipients&#x27; identities. Token ownership can expose sensitive personal information. While individuals may wish to donate to a specific organization or country, they might prefer not to disclose a link between themselves and the recipient simultaneously. Standardizing stealth address generation represents a significant step towards unlinkable interactions, since such privacy-enhancing solutions require standards to achieve widespread adoption. Consequently, it is crucial to focus on developing generalizable approaches for implementing related solutions.&lt;&#x2F;p&gt;
&lt;p&gt;The stealth address specification standardizes a protocol for generating and locating stealth addresses, facilitating the transfer of assets without requiring prior interaction with the recipient. This enables recipients to verify the receipt of a transfer without the need to interact with the blockchain and query account balances. Importantly, stealth addresses enable token transfer recipients to verify receipt while maintaining their privacy, as only the recipient can recognize themselves as the recipient of the transfer.&lt;&#x2F;p&gt;
&lt;p&gt;The authors recognize the trade-off between on- and off-chain efficiency. Although incorporating a Monero-like view tags mechanism enables recipients to parse announcements more efficiently, it adds complexity to the announcement event.&lt;&#x2F;p&gt;
&lt;p&gt;The recipient&#x27;s address and the &lt;code&gt;viewTag&lt;&#x2F;code&gt; must be included in the announcement event, allowing users to quickly verify ownership without querying the chain for positive account balances.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC is fully backward compatible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deployment-method&quot;&gt;Deployment Method&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ERC5564Announcer&lt;&#x2F;code&gt; contract is deployed at &lt;code&gt;0x55649E01B5Df198D18D95b5cc5051630cfD45564&lt;&#x2F;code&gt; using &lt;code&gt;CREATE2&lt;&#x2F;code&gt; via the deterministic deployer at &lt;code&gt;0x4e59b44847b379578588920ca78fbf26c0b4956c&lt;&#x2F;code&gt; with a salt of &lt;code&gt;0xd0103a290d760f027c9ca72675f5121d725397fb2f618f05b6c44958b25b4447&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;You can find the implementation of the &lt;code&gt;ERC5564Announcer&lt;&#x2F;code&gt; contract &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5564&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC5564Announcer.sol&quot;&gt;here&lt;&#x2F;a&gt; and the interface &lt;code&gt;IERC5564Announcer.sol&lt;&#x2F;code&gt; &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5564&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;interfaces&#x2F;IERC5564Announcer.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dos-countermeasures&quot;&gt;DoS Countermeasures&lt;&#x2F;h3&gt;
&lt;p&gt;There are potential denial of service (DoS) attack vectors that are not mitigated by network transaction fees. Stealth transfer senders cause an externality for recipients, as parsing announcement events consumes computational resources that are not compensated with gas. Therefore, spamming announcement events &lt;em&gt;can&lt;&#x2F;em&gt; be a detriment to the user experience, as it &lt;em&gt;can&lt;&#x2F;em&gt; lead to longer parsing times.
We consider the incentives to carry out such an attack to be low because &lt;strong&gt;no monetary benefit can be obtained&lt;&#x2F;strong&gt;
However, to tackle potential spam, parsing providers may adopt their own anti-DoS attack methods. These may include ignoring the spamming users when serving announcements to users or, less harsh, de-prioritizing them when ordering the announcements. The indexed &lt;code&gt;caller&lt;&#x2F;code&gt; keyword may help parsing providers to effectively filter known spammers.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, parsing providers have a few options to counter spam, such as introducing staking mechanisms or requiring senders to pay a &lt;code&gt;toll&lt;&#x2F;code&gt; before including their &lt;code&gt;Announcement&lt;&#x2F;code&gt;. Moreover, a Staking mechanism may allow users to stake an unslashable amount of ETH (similarly to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4337&#x2F;&quot;&gt;ERC-4337&lt;&#x2F;a&gt;), to help mitigate potential spam through &lt;em&gt;sybil attacks&lt;&#x2F;em&gt; and enable parsing providers filtering spam more effectively.
Introducing a &lt;code&gt;toll&lt;&#x2F;code&gt;, paid by sending users, would simply put a cost on each stealth address transaction, making spamming economically unattractive.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recipients-transaction-costs&quot;&gt;Recipients&#x27; transaction costs&lt;&#x2F;h3&gt;
&lt;p&gt;The funding of the stealth address wallet represents a known issue that might breach privacy. The wallet that funds the stealth address MUST NOT have any physical connection to the stealth address owner in order to fully leverage the privacy improvements.&lt;&#x2F;p&gt;
&lt;p&gt;Thus, the sender may attach a small amount of ETH to each stealth address transaction, thereby sponsoring subsequent transactions of the recipient.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Referable NFT</title>
        <published>2022-08-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Saber Yu</name><uri>https://github.com/OniReimu</uri>
	</author>
	
	<author>
		<name>Qin Wang</name><email>qin.wang@data61.csiro.au</email>
	</author>
	
	<author>
		<name>Shange Fu</name><email>shange.fu@monash.edu</email>
	</author>
	
	<author>
		<name>Yilin Sai</name><email>yilin.sai@data61.csiro.au</email>
	</author>
	
	<author>
		<name>Shiping Chen</name><email>shiping.chen@data61.csiro.au</email>
	</author>
	
	<author>
		<name>Sherry Xu</name><email>xiwei.xu@data61.csiro.au</email>
	</author>
	
	<author>
		<name>Jiangshan Yu</name><email>jiangshan.yu@monash.edu</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5521/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310" />
        

        <id>https://wg-eips.ritovision.com/5521/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5521"
            label="ERC-5521" />
        

        
        

        
        <summary type="html">An ERC-721 extension to construct reference relationships among NFTs</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5521/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. It proposes two referable indicators, referring and referred, and a time-based indicator &lt;code&gt;createdTimestamp&lt;&#x2F;code&gt;. The relationship between each NFT forms a directed acyclic graph (DAG). The standard allows users to query, track and analyze their relationships.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5521&#x2F;.&#x2F;assets&#x2F;system-arch.png&quot; alt=&quot;System Architecture&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many scenarios require the inheritance, reference, and extension of NFTs. For instance, an artist may develop his NFT work based on a previous NFT, or a DJ may remix his record by referring to two pop songs, etc. A gap in existing NFT standards is the absence of established relationships between an NFT and its original creator. This void isolates NFTs, rendering the sale of each one a one-off transaction, thereby obstructing creators from accruing the full value of their intellectual property over time.&lt;&#x2F;p&gt;
&lt;p&gt;In this sense, proposing a referable solution for existing NFTs that enables efficient queries on cross-references is necessary. By introducing a reference relationship between NFTs, a sustainable economic model can be established to incentivize continued engagement in creating, using, and promoting NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including &lt;code&gt;referring&lt;&#x2F;code&gt; and &lt;code&gt;referred&lt;&#x2F;code&gt; relationships, aiding in the formation of a Direct Acyclic Graph (DAG)-based NFT network. This structure provides a transparent graphical historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew.&lt;&#x2F;p&gt;
&lt;p&gt;An intuitive example: users can create new NFTs (C, D, E) by referencing existing ones (A, B), while the &lt;code&gt;referred&lt;&#x2F;code&gt; function informs the original NFTs (A, B) about their citations (e.g., A ← D; C ← E; B ← E, and A ← E). Here, the &lt;code&gt;createdTimestamp&lt;&#x2F;code&gt; (block-level) serves as an indicator for the creation time of NFTs (A, B, C, D, E).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;&#x2F;h3&gt;
&lt;p&gt;This standard provides several advantages:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Clear ownership inheritance&lt;&#x2F;em&gt;: This standard extends the static NFT into a virtually extensible NFT network. Artists do not have to create work isolated from others. The ownership inheritance avoids reinventing the same wheel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Incentive Compatibility&lt;&#x2F;em&gt;: This standard clarifies the referable relationship across different NFTs, helping to integrate multiple up-layer incentive models for both original NFT owners and new creators.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Easy Integration&lt;&#x2F;em&gt;: This standard makes it easier for the existing token standards or third-party protocols. For instance, the rNFT can be applied to rentable scenarios (cf. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5006&#x2F;&quot;&gt;ERC-5006&lt;&#x2F;a&gt; to build a hierarchical rental market, where multiple users can rent the same NFT during the same time or one user can rent multiple NFTs during the same duration).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Scalable Interoperability&lt;&#x2F;em&gt;: This standard enables cross-contract references, giving a scalable adoption for the broader public with stronger interoperability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UpdateNode&lt;&#x2F;code&gt;: event emitted when &lt;code&gt;setNode&lt;&#x2F;code&gt; is invoked;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;safeMint&lt;&#x2F;code&gt;: mint a new rNFT;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;setNode&lt;&#x2F;code&gt;: set the referring list of an rNFT and update the referred list of each one in the referring list;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setNodeReferring&lt;&#x2F;code&gt;: set the referring list of an rNFT;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;setNodeReferred&lt;&#x2F;code&gt;: set the referred list of the given rNFTs sourced from different contracts;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setNodeReferredExternal&lt;&#x2F;code&gt;: set the referred list of the given rNFTs sourced from external contracts;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referringOf&lt;&#x2F;code&gt;: get the referring list of an rNFT;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referredOf&lt;&#x2F;code&gt;: get the referred list of an rNFT;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;createdTimestampOf&lt;&#x2F;code&gt;: get the timestamp of an rNFT when it is being created.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Implementers of this standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have all of the following functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;introspection&#x2F;IERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC_5521&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Logged when a node in the rNFT gets referred and &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the `node` (i.e., an rNFT) is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateNode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;                     address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                     address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _address_referringList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                     uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenIds_referringList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                     address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _address_referredList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                     uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenIds_referredList&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referred list of an rNFT associated with different contract addresses and update the referring list of each one in the referred list. Checking the duplication of `addresses` and `tokenIds` is **RECOMMENDED**.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `tokenId` of rNFT being set. `addresses` of the contracts in which rNFTs with `tokenIds` being referred accordingly. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @requirement &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the size of `addresses` **MUST** be the same as that of `tokenIds`;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - once the size of `tokenIds` is non-zero, the inner size **MUST** also be non-zero;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the `tokenId` **MUST** be unique within the same contract;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the `tokenId` **MUST NOT** be the same as `tokenIds[i][j]` if `addresses[i]` is essentially `address(this)`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get the referring list of an rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; referring mapping of the rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referringOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get the referred list of an rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; referred mapping of the rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referredOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get the timestamp of an rNFT when is being created.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; timestamp of the rNFT when is being created with uint256 format.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createdTimestampOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check supported interfaces, adhereing to ERC165.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referred list of an rNFT associated with external contract addresses. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_tokenIds` of rNFTs associated with the contract address `_address` being referred by the rNFT with `tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @requirement&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - `_address` **MUST NOT** be the same as `address(this)` where `this` is executed by an external contract where `TargetContract` interface is implemented.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNodeReferredExternal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referringOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referredOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createdTimestampOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;is-this-event-informative-enough&quot;&gt;Is this event informative enough?&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;UpdateNode&lt;&#x2F;code&gt;: This event disseminates crucial information, including the rNFT ID, its owner, and lists of contract addresses&#x2F;IDs with rNFTs referring to or referred by the subject rNFT. This data set enables stakeholders to efficiently manage and navigate the complex web of relationships inherent in the rNFT ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers are free to choose to use a struct (a recommended struct is given in the Reference Implementation), or several separate mappings, or whatever other storage mechanism. Whichever mechanism chosen has no observable effect on the behaviour of the contract, as long as its output can fulfill the &lt;code&gt;UpdateNode&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-createdtimestampof&quot;&gt;Why &lt;code&gt;createdTimestampOf&lt;&#x2F;code&gt;?&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;createdTimestamp&lt;&#x2F;code&gt;: A key principle of this standard is that an rNFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for rNFTs are thus essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where &lt;code&gt;createdTimestamp = block.timestamp&lt;&#x2F;code&gt; Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two rNFTs within the same block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-is-cross-contract-reference-performed&quot;&gt;How is cross-contract reference performed?&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;setNodeReferredExternal&lt;&#x2F;code&gt;: This function operates conditionally, dependent on successful interface verification in external contracts. Such selective invocation ensures backward compatibility and integration with existing contracts, provided they adhere to specified interfaces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard can be fully &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; compatible by adding an extension function set.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5521&#x2F;.&#x2F;assets&#x2F;ERC_5521.test.js&quot;&gt;ERC_5521.test.js&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The recommended implementation is demonstrated as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Relationship&lt;&#x2F;code&gt;: a structure that contains &lt;code&gt;referring&lt;&#x2F;code&gt;, &lt;code&gt;referred&lt;&#x2F;code&gt;, &lt;code&gt;referringKeys&lt;&#x2F;code&gt;, &lt;code&gt;referredKeys&lt;&#x2F;code&gt;, &lt;code&gt;createdTimestamp&lt;&#x2F;code&gt;, and other customized and optional attributes (i.e., not necessarily included in the standard) such as &lt;code&gt;privityOfAgreement&lt;&#x2F;code&gt; recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or &lt;code&gt;profitSharing&lt;&#x2F;code&gt; recording the profit sharing of &lt;code&gt;referring&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referring&lt;&#x2F;code&gt;: an out-degree indicator, used to show the users this NFT refers to;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referred&lt;&#x2F;code&gt;: an in-degree indicator, used to show the users who have refereed this NFT;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referringKeys&lt;&#x2F;code&gt;: a helper for mapping conversion of out-degree indicators, used for events;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referredKeys&lt;&#x2F;code&gt;: a helper for mapping conversion of in-degree indicators, used for events;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;createdTimestamp&lt;&#x2F;code&gt;: a time-based indicator, used to compare the timestamp of mint, which should not be editable anyhow by callers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;referringOf&lt;&#x2F;code&gt; and &lt;code&gt;referredOf&lt;&#x2F;code&gt;: First, the current &lt;code&gt;referringOf&lt;&#x2F;code&gt; and &lt;code&gt;referredOf&lt;&#x2F;code&gt; allow cross-contract looking up, while this cannot be done by directly accessing &lt;code&gt;_relationship&lt;&#x2F;code&gt;. Secondly, only if privacy is not a concern, making &lt;code&gt;_relationship&lt;&#x2F;code&gt; public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach.  For example, if &lt;code&gt;_relationship&lt;&#x2F;code&gt; includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the &lt;code&gt;Relationship&lt;&#x2F;code&gt; can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;convertMap&lt;&#x2F;code&gt;: This function is essential for retrieving the full mapping contents within a struct. Even if &lt;code&gt;_relationship&lt;&#x2F;code&gt; is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, &lt;code&gt;convertMap&lt;&#x2F;code&gt; is necessary to fulfill our event emission requirements.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC_5521.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC_5521&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC_5521&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;TargetContract&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Relationship&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; referring&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; referred&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; referringKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; referredKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; createdTimestamp&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unix timestamp when the rNFT is being created&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; extensible parameters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Relationship&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; contractOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;name_, symbol_) &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        contractOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; require(msg.sender == contractOwner, &amp;quot;ERC_rNFT: Only contract owner can mint&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        setNode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referred list of an rNFT associated with different contract addresses and update the referring list of each one in the referred list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of rNFTs, recommended to check duplication at the caller&amp;#39;s end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&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&gt;            addresses&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;Addresses and TokenID arrays must have the same length&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC_5521: the referring list cannot be empty&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        setNodeReferring&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        setNodeReferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenIds&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referring list of an rNFT associated with different contract addresses &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of rNFTs associated with addresses, recommended to check duplication at the caller&amp;#39;s end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNodeReferring&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: transfer caller is not owner nor approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referring&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referringKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add the address if it&amp;#39;s a new entry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referring&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&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&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&gt;        relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;createdTimestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        emitEvents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referred list of an rNFT associated with different contract addresses &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of rNFTs associated with addresses, recommended to check duplication at the caller&amp;#39;s end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNodeReferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;                    Relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referred&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referredKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add the address if it&amp;#39;s a new entry&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 class=&quot;z-keyword&quot;&gt;                    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: self-reference not allowed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;createdTimestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC_5521: the referred rNFT needs to be a predecessor&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make sure the reference complies with the timing sequence&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;                    relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referred&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;                    emitEvents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;z-keyword&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&gt;                TargetContract targetContractInstance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                bool&lt;&#x2F;span&gt;&lt;span&gt; isSupports &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;isSupports&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;                    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The target contract supports the interface, safe to call functions of the interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;setNodeReferredExternal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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;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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the referred list of an rNFT associated with different contract addresses &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; array of rNFTs associated with addresses, recommended to check duplication at the caller&amp;#39;s end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setNodeReferredExternal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; _tokenIds&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;            Relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referred&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referredKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add the address if it&amp;#39;s a new entry&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: this must be an external contract address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;createdTimestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC_5521: the referred rNFT needs to be a predecessor&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make sure the reference complies with the timing sequence&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;            relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referred&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            emitEvents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_tokenIds&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the referring list of an rNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The considered rNFT, _address The corresponding contract address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; referring mapping of an rNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referringOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC_5521&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referringKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_address &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: token ID not existed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;_referringKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            TargetContract targetContractInstance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: target contract not supported&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;_referringKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;referringOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_referringKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the referred list of an rNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The considered rNFT, _address The corresponding contract address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; referred mapping of an rNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; referredOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC_5521&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referredKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_address &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: token ID not existed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;_referredKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            TargetContract targetContractInstance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: target contract not supported&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;_referredKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;referredOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_referredKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the timestamp of an rNFT when is being created.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; timestamp of the rNFT when is being created with uint256 format.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createdTimestampOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; createdTimestamp&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_address &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: token ID not existed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            Relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;            createdTimestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;createdTimestamp&lt;&#x2F;span&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;span class=&quot;z-keyword&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&gt;            TargetContract targetContractInstance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC_5521: target contract not supported&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            createdTimestamp &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; targetContractInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;createdTimestampOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; createdTimestamp&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC165-supportsInterface}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC_5521&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC_5521&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&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 class=&quot;z-keyword&quot;&gt;            ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TargetContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&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 class=&quot;z-keyword&quot;&gt;            ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice Emit an event of UpdateNode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; emitEvents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referringKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referredKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateNode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referringKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referringValues&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referredKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _referredValues&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; @notice Convert a specific `local` token mapping to a key array and a value array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; convertMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; isReferring&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;        Relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; relationship &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _relationship&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; returnKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; returnValues&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;isReferring&lt;&#x2F;span&gt;&lt;span&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&gt;            returnKeys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referringKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            returnValues &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;returnKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; returnKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;                returnValues&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referring&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;returnKeys&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;            returnKeys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referredKeys&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            returnValues &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;returnKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; returnKeys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&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&gt;                returnValues&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; relationship&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;referred&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;returnKeys&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;returnKeys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; returnValues&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;timestamp&quot;&gt;Timestamp&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;createdTimestamp&lt;&#x2F;code&gt; only covers the block-level timestamp (based on block headers), which does not support fine-grained comparisons such as transaction-level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ownership-and-reference&quot;&gt;Ownership and Reference&lt;&#x2F;h3&gt;
&lt;p&gt;The change of ownership has nothing to do with the reference relationship. Normally, the distribution of profits complies with the agreement when the NFT was being created regardless of the change of ownership unless specified in the agreement.&lt;&#x2F;p&gt;
&lt;p&gt;Referring a token will not refer to its descendants by default. In the case that only a specific child token gets referred, it means the privity of the contract will involve nobody other than the owner of this specific child token. Alternatively, a chain-of-reference all the way from the root token to a specific very bottom child token (from root to leaf) can be constructed and recorded in the &lt;code&gt;referring&lt;&#x2F;code&gt; to explicitly define the distribution of profits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;open-minting-and-relationship-risks&quot;&gt;Open Minting and Relationship Risks&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;safeMint&lt;&#x2F;code&gt; function has been deliberately designed to allow unrestricted minting and relationship setting, akin to the open referencing system seen in platforms such as Google Scholar. This decision facilitates strong flexibility, enabling any user to create and define relationships between NFTs without centralized control. While this design aligns with the intended openness of the system, it inherently carries certain risks. Unauthorized or incorrect references can be created, mirroring the challenges faced in traditional scholarly referencing, where erroneous citations may occur. Additionally, the open nature may expose the system to potential abuse by malicious actors, who might manipulate relationships or inflate the token supply. It is important to recognize that these risks are not considered design flaws but intentional trade-offs, which balance the system&#x27;s flexibility against potential reliability concerns.&lt;&#x2F;p&gt;
&lt;p&gt;Stakeholders should be aware that the on-chain data integrity guarantees extend only to what has been recorded on the blockchain and do not preclude the possibility of off-chain errors or manipulations. Thus, users and integrators should exercise caution and judgment in interpreting and using the relationships and other data provided by this system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>NFT Author Information and Consent</title>
        <published>2022-07-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Samuele Marro</name><uri>https://github.com/samuelemarro</uri>
	</author>
	
	<author>
		<name>Luca Donno</name><uri>https://github.com/lucadonnoh</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5375/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5375-nft-authorship/10182" />
        

        <id>https://wg-eips.ritovision.com/5375/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5375"
            label="ERC-5375" />
        

        
        

        
        <summary type="html">An extension of EIP-721 for NFT authorship and author consent.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5375/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes a JSON format for storing off-chain information about NFT authors. Specifically, it adds a new field which provides a list of author names, addresses, and proofs of &lt;em&gt;authorship consent&lt;&#x2F;em&gt;: proofs that the authors have agreed to be named as authors. Note that a proof of authorship &lt;em&gt;consent&lt;&#x2F;em&gt; is not a proof of authorship: an address can consent without having authored the NFT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There is currently no standard to identify authors of an NFT, and existing techniques have issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Using the mint &lt;code&gt;tx.origin&lt;&#x2F;code&gt; or &lt;code&gt;msg.sender&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Assumes that the minter and the author are the same&lt;&#x2F;li&gt;
&lt;li&gt;Does not support multiple authors&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Using the first Transfer event for a given ID
&lt;ul&gt;
&lt;li&gt;Contract&#x2F;minter can claim that someone else is the author without their consent&lt;&#x2F;li&gt;
&lt;li&gt;Does not support multiple authors&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Using a custom method&#x2F;custom JSON field
&lt;ul&gt;
&lt;li&gt;Requires per-contract support by NFT platforms&lt;&#x2F;li&gt;
&lt;li&gt;Contract&#x2F;minter can claim that someone else is the author without their consent&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first practice is the most common. However, there are several situations where the minter and the author might not be the same, such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;NFTs minted by a contract&lt;&#x2F;li&gt;
&lt;li&gt;Lazy minting&lt;&#x2F;li&gt;
&lt;li&gt;NFTs minted by an intermediary (which can be particularly useful when the author is not tech-savvy and&#x2F;or the minting process is convoluted)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This document thus defines a standard which allows the minter to provide authorship information, while also preventing authorship claims without the author&#x27;s consent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;All addresses used in this standard MUST follow the casing rules described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;55&#x2F;&quot;&gt;EIP-55&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Authors&lt;&#x2F;strong&gt;: creators of an NFT&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Minter&lt;&#x2F;strong&gt;: entity responsible for the actual minting transaction; the minter and the authors MAY be the same&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt;: entity that wants to verify the authorship of an NFT (e.g. a user or an NFT marketplace)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Author Consent Proof (ACP)&lt;&#x2F;strong&gt;: a signed message that proves that the signer agrees to be considered the author of the NFT&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;authorship-support&quot;&gt;Authorship Support&lt;&#x2F;h3&gt;
&lt;p&gt;The standard introduces a new JSON field, named &lt;code&gt;authorInfo&lt;&#x2F;code&gt;. It provides a REQUIRED interface for authorship claiming, as well as an OPTIONAL interface for author consent proofs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;authorInfo&lt;&#x2F;code&gt; is a top-level field of the NFT metadata. Specifically:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If a contract supports the metadata extension for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;, the JSON document pointed by &lt;code&gt;tokenURI(uint256 _tokenId)&lt;&#x2F;code&gt; MUST include the top-level field &lt;code&gt;authorInfo&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;If a contract supports the metadata extension for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;, the JSON document pointed by &lt;code&gt;uri(uint256 _id)&lt;&#x2F;code&gt; MUST include a top-level field &lt;code&gt;authorInfo&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The JSON schema of &lt;code&gt;authorInfo&lt;&#x2F;code&gt; (named &lt;code&gt;ERC5375AuthorInfoSchema&lt;&#x2F;code&gt;) is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;consentInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Helper fields for consent verification&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP-155 chain id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;NFT id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contractAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x-prefixed address of the smart contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;authors&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC5375AuthorSchema&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;authors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that &lt;code&gt;authors&lt;&#x2F;code&gt; MAY be an empty array.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ERC5375AuthorSchema&lt;&#x2F;code&gt; is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x-prefixed address of the author&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;consent&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC5375AuthorConsentSchema&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Author consent information&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Moreover, if the &lt;code&gt;consent&lt;&#x2F;code&gt; field is present, the &lt;code&gt;consentInfo&lt;&#x2F;code&gt; field of &lt;code&gt;authorInfo&lt;&#x2F;code&gt; MUST be present.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ERC5375AuthorConsentSchema&lt;&#x2F;code&gt; is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;consentData&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;NFT authorship consent schema version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;issuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x-prefixed address of the author&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;metadataFields&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;issuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;metadataFields&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;publicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EVM public key of the author&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP-712 signature of the consent message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;consentData&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;publicKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where &lt;code&gt;metadataFields&lt;&#x2F;code&gt; is an object containing the JSON top-level fields (excluding &lt;code&gt;authorInfo&lt;&#x2F;code&gt;) that the author will certify. Note that the keys of &lt;code&gt;metadataFields&lt;&#x2F;code&gt; MAY be a (potentially empty) subset of the set of fields.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;consentData&lt;&#x2F;code&gt; MAY support additional fields as defined by other EIPs. &lt;code&gt;consentData&lt;&#x2F;code&gt; MUST contain all the information (which is not already present in other fields) required to verify the validity of an authorship consent proof.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;author-consent&quot;&gt;Author Consent&lt;&#x2F;h3&gt;
&lt;p&gt;Consent is obtained by signing an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; compatible message. Specifically, the structure is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Author&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; subject&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; metadata&lt;&#x2F;span&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;where &lt;code&gt;subject&lt;&#x2F;code&gt; is the address of the NFT contract, &lt;code&gt;tokenId&lt;&#x2F;code&gt; is the id of the NFT and &lt;code&gt;metadata&lt;&#x2F;code&gt; is the JSON encoding of the fields listed in &lt;code&gt;metadataFields&lt;&#x2F;code&gt;. &lt;code&gt;metadata&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST contain exactly the same fields as the ones listed in &lt;code&gt;metadataFields&lt;&#x2F;code&gt;, in the same order&lt;&#x2F;li&gt;
&lt;li&gt;MUST escape all non-ASCII characters. If the escaped character contains hexadecimal letters, they MUST be uppercase&lt;&#x2F;li&gt;
&lt;li&gt;MUST not contain any whitespace that is not part of a field name or value&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For example, if the top-level JSON fields are:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The Holy Hand Grenade of Antioch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Throw in the general direction of your favorite rabbit, et voilà&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;damage&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;authors&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-invalid z-illegal&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&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;and the content of &lt;code&gt;metadataFields&lt;&#x2F;code&gt; is &lt;code&gt;[&quot;name&quot;, &quot;description&quot;]&lt;&#x2F;code&gt;, the content of &lt;code&gt;metadata&lt;&#x2F;code&gt; is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The Holy Hand Grenade of Antioch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Throw in the general direction of your favorite rabbit, et voil&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\u00E0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;Similarly to &lt;code&gt;consentData&lt;&#x2F;code&gt;, this structure MAY support additional fields as defined by other EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;The domain separator structure is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP712Domain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; version&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; chainId&lt;&#x2F;span&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;where &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;version&lt;&#x2F;code&gt; are the same fields described in &lt;code&gt;consentData&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This structure MAY support additional fields as defined by other EIPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;author-consent-verification&quot;&gt;Author Consent Verification&lt;&#x2F;h3&gt;
&lt;p&gt;Verification is performed using EIP-712 on an author-by-author basis. Specifically, given a JSON document D1, a consent proof is valid if all of the following statements are true:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;D1 has a top-level &lt;code&gt;authorInfo&lt;&#x2F;code&gt; field that matches &lt;code&gt;ERC5375AuthorInfoSchema&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;consent&lt;&#x2F;code&gt; exists and matches &lt;code&gt;ERC5375AuthorConsentSchema&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;If calling &lt;code&gt;tokenURI&lt;&#x2F;code&gt; (for EIP-721) or &lt;code&gt;uri&lt;&#x2F;code&gt; (for EIP-1155) returns the URI of a JSON document D2, all the top-level fields listed in &lt;code&gt;metadataFields&lt;&#x2F;code&gt; MUST exist and have the same value;&lt;&#x2F;li&gt;
&lt;li&gt;The EIP-712 signature in &lt;code&gt;signature&lt;&#x2F;code&gt; (computed using the fields specified in the JSON document) is valid;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Verifiers MUST NOT assume that an NFT with a valid consent proof from address X means that X is the actual author. On the other hand, verifiers MAY assume that if an NFT does not provide a valid consent proof for address X, then X is not the actual author.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-provide-only-an-author-consent-proof&quot;&gt;Why provide only an author consent proof?&lt;&#x2F;h3&gt;
&lt;p&gt;Adding support for full authorship proofs (i.e. Alice is the author and no one else is the author) requires a protocol to prove that someone is the only author of an NFT.
In other words, we need to answer the question: &quot;Given an NFT Y and a user X claiming to be the author, is X the original author of Y?&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;For the sake of the argument, assume that there exists a protocol that, given an NFT Y, can determine the original author of Y. Even if such method existed, an attacker could slightly modify Y, thus obtaining a new NFT Y&#x27;, and rightfully claim to be the author of Y&#x27;, despite the fact that it is not an original work. Real-world examples include changing some pixels of an image or replacing some words of a text with synonyms.
Preventing this behavior would require a general formal definition of when two NFTs are semantically equivalent. Even if defining such a concept were possible, it would still be beyond the scope of this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this issue is also present when using the minter&#x27;s address as a proxy for the author.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-off-chain&quot;&gt;Why off-chain?&lt;&#x2F;h3&gt;
&lt;p&gt;There are three reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Adding off-chain support does not require modifications to existing smart contracts;&lt;&#x2F;li&gt;
&lt;li&gt;Off-chain storage is usually much cheaper than on-chain storage, thus reducing the implementation barrier;&lt;&#x2F;li&gt;
&lt;li&gt;While there may be some use cases for full on-chain authorship proofs (e.g. a marketplace providing special features for authors), there are limited applications for on-chain author consent, due to the fact that it is mostly used by users to determine the subjective value of an NFT.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-repeat-id-chainid-and-contractaddress&quot;&gt;Why repeat id, chainId and contractAddress?&lt;&#x2F;h3&gt;
&lt;p&gt;In many cases, this data can be derived from contextual information. However, requiring their inclusion in the JSON document ensures that author consent can be verified using only the JSON document.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-implement-a-revocation-system&quot;&gt;Why not implement a revocation system?&lt;&#x2F;h3&gt;
&lt;p&gt;Authorship is usually final: either someone created an NFT or they didn&#x27;t. Moreover, a revocation system would impose additional implementation requirements on smart contracts and increase the complexity of verification. Smart contracts MAY implement a revocation system, such as the one defined in other EIPs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;why-escape-non-ascii-characters-in-the-signature-message&quot;&gt;Why escape non-ASCII characters in the signature message?&lt;&#x2F;h4&gt;
&lt;p&gt;EIP-712 is designed with the possibility of on-chain verification in mind; while on-chain verification is not a priority for this EIP, non-ASCII characters are escaped due to the high complexity of dealing with non-ASCII strings in smart contracts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;usability-improvements-for-authors&quot;&gt;Usability Improvements for Authors&lt;&#x2F;h3&gt;
&lt;p&gt;Since the author only needs to sign an EIP-712 message, this protocol allows minters to handle the technical aspects of minting while still preserving the secrecy of the author&#x27;s wallet. Specifically, the author only needs to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Obtain an EVM wallet;&lt;&#x2F;li&gt;
&lt;li&gt;Learn how to read and sign a EIP-712 message (which can often be simplified by using a Dapp)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;without needing to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Obtain the chain&#x27;s native token (e.g. through trading or bridging);&lt;&#x2F;li&gt;
&lt;li&gt;Sign a transaction;&lt;&#x2F;li&gt;
&lt;li&gt;Understand the pricing mechanism of transactions;&lt;&#x2F;li&gt;
&lt;li&gt;Verify if a transaction has been included in a block&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This reduces the technical barrier for authors, thus increasing the usability of NFTs, without requiring authors to hand over their keys to a tech-savvy intermediary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;limitations-of-address-based-consent&quot;&gt;Limitations of Address-Based Consent&lt;&#x2F;h3&gt;
&lt;p&gt;The standard defines a protocol to verify that a certain &lt;em&gt;address&lt;&#x2F;em&gt; provided consent. However, it does not guarantee that the address corresponds to the expected author (such as the one provided in the &lt;code&gt;name&lt;&#x2F;code&gt; field). Proving a link between an address and the entity behind it is beyond the scope of this document.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;attacks&quot;&gt;Attacks&lt;&#x2F;h3&gt;
&lt;p&gt;A potential attack that exploits this EIP involves tricking authors into signing authorship consent messages against their wishes. For this reason, authors MUST verify that all signature fields match the required ones.&lt;&#x2F;p&gt;
&lt;p&gt;A more subtle approach involves not adding important fields to &lt;code&gt;metadataFields&lt;&#x2F;code&gt;. By doing so, the author signature might be valid even if the minter changes critical information.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deprecated-features&quot;&gt;Deprecated Features&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;ERC5375AuthorInfoSchema&lt;&#x2F;code&gt; also originally included a field to specify a human-readable name for the author (without any kind of verification). This was scrapped due to the high risk of author spoofing, i.e.:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Alice mints an NFT using Bob&#x27;s name and Alice&#x27;s address&lt;&#x2F;li&gt;
&lt;li&gt;Charlie does not check the address and instead relies on the provided name&lt;&#x2F;li&gt;
&lt;li&gt;Charlie buys Alice&#x27;s NFT while believing that it was created by Bob&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For this reason, smart contract developers SHOULD NOT add support for unverifiable information to the JSON document. We believe that the most secure way to provide complex authorship information (e.g. the name of the author) is to prove that the information is associated with the &lt;em&gt;author&#x27;s address&lt;&#x2F;em&gt;, instead of with the NFT itself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replay-attack-resistance&quot;&gt;Replay Attack Resistance&lt;&#x2F;h3&gt;
&lt;p&gt;The chain id, the contract address and the token id uniquely identify an NFT; for this reason, there is no need to implement additional replay attack countermeasures (e.g. a nonce system).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Light Contract Ownership</title>
        <published>2022-07-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>William Entriken</name><uri>https://github.com/fulldecent</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5313/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5313-light-contract-ownership/10052" />
        

        <id>https://wg-eips.ritovision.com/5313/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5313"
            label="ERC-5313" />
        

        
        

        
        <summary type="html">An interface for identifying ownership of contracts</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5313/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines the minimum interface required to identify an account that controls a contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This is a slimmed-down alternative to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;173&#x2F;&quot;&gt;EIP-173&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key word “MUST” in this document is to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;Every contract compliant with this EIP MUST implement the &lt;code&gt;EIP5313&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-5313 Light Contract Ownership Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP5313&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the address of the owner    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Key factors influencing the standard:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Minimize the number of functions in the interface&lt;&#x2F;li&gt;
&lt;li&gt;Backwards compatibility with existing contracts&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This standard can be (and has been) extended by other standards to add additional ownership functionality. The smaller scope of this specification allows more and more straightforward ownership implementations, see limitations explained in EIP-173 under &quot;other schemes that were considered&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Implementing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt; could be a valuable addition to this interface specification. However, this EIP is being written to codify existing protocols that connect contracts (often NFTs), with third-party websites (often a well-known NFT marketplace).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Every contract that implements EIP-173 already implements this specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Because this specification does not extend EIP-165, calling this EIP&#x27;s &lt;code&gt;owner&lt;&#x2F;code&gt; function cannot result in complete certainty that the result is indeed the owner. For example, another function with the same function signature may return some value that is then interpreted to be the true owner. If this EIP is used solely to identify if an account is the owner of a contract, then the impact of this risk is minimized. But if the interrogator is, for example, sending a valuable NFT to the identified owner of any contract on the network, then the risk is heightened.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Retrieval of EIP-712 domain</title>
        <published>2022-07-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5267/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5267-retrieval-of-eip-712-domain/9951" />
        

        <id>https://wg-eips.ritovision.com/5267/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5267"
            label="ERC-5267" />
        

        
        

        
        <summary type="html">A way to describe and retrieve an EIP-712 domain to securely integrate EIP-712 signatures.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5267/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP complements &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; by standardizing how contracts should publish the fields and values that describe their domain. This enables applications to retrieve this description and generate appropriate domain separators in a general way, and thus integrate EIP-712 signatures securely and scalably.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;EIP-712 is a signature scheme for complex structured messages. In order to avoid replay attacks and mitigate phishing, the scheme includes a &quot;domain separator&quot; that makes the resulting signature unique to a specific domain (e.g., a specific contract) and allows user-agents to inform end users the details of what is being signed and how it may be used. A domain is defined by a data structure with fields from a predefined set, all of which are optional, or from extensions. Notably, EIP-712 does not specify any way for contracts to publish which of these fields they use or with what values. This has likely limited adoption of EIP-712, as it is not possible to develop general integrations, and instead applications find that they need to build custom support for each EIP-712 domain. A prime example of this is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2612&#x2F;&quot;&gt;EIP-2612&lt;&#x2F;a&gt; (permit), which has not been widely adopted by applications even though it is understood to be a valuable improvement to the user experience. The present EIP defines an interface that can be used by applications to retrieve a definition of the domain that a contract uses to verify EIP-712 signatures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;Compliant contracts MUST define &lt;code&gt;eip712Domain&lt;&#x2F;code&gt; exactly as declared below. All specified values MUST be returned even if they are not used, to ensure proper decoding on the client side.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; eip712Domain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 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 class=&quot;z-support&quot;&gt;    bytes1&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; extensions&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The return values of this function MUST describe the domain separator that is used for verification of EIP-712 signatures in the contract. They describe both the form of the &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; struct (i.e., which of the optional fields and extensions are present) and the value of each field, as follows.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fields&lt;&#x2F;code&gt;: A bit map where bit &lt;code&gt;i&lt;&#x2F;code&gt; is set to 1 if and only if domain field &lt;code&gt;i&lt;&#x2F;code&gt; is present (&lt;code&gt;0 ≤ i ≤ 4&lt;&#x2F;code&gt;). Bits are read from least significant to most significant, and fields are indexed in the order that is specified by EIP-712, identical to the order in which they are listed in the function type.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;version&lt;&#x2F;code&gt;, &lt;code&gt;chainId&lt;&#x2F;code&gt;, &lt;code&gt;verifyingContract&lt;&#x2F;code&gt;, &lt;code&gt;salt&lt;&#x2F;code&gt;: The value of the corresponding field in &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt;, if present according to &lt;code&gt;fields&lt;&#x2F;code&gt;. If the field is not present, the value is unspecified. The semantics of each field is defined in EIP-712.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;extensions&lt;&#x2F;code&gt;: A list of EIP numbers, each of which MUST refer to an EIP that extends EIP-712 with new domain fields, along with a method to obtain the value for those fields, and potentially conditions for inclusion. The value of &lt;code&gt;fields&lt;&#x2F;code&gt; does not affect their inclusion.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The return values of this function (equivalently, its EIP-712 domain) MAY change throughout the lifetime of a contract, but changes SHOULD NOT be frequent. The &lt;code&gt;chainId&lt;&#x2F;code&gt; field, if used, SHOULD change to mirror the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; id of the underlying chain. Contracts MAY emit the event &lt;code&gt;EIP712DomainChanged&lt;&#x2F;code&gt; defined below to signal that the domain could have changed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP712DomainChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&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;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;A notable application of EIP-712 signatures is found in EIP-2612 (permit), which specifies a &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; function that returns a &lt;code&gt;bytes32&lt;&#x2F;code&gt; value (the actual domain separator, i.e., the result of &lt;code&gt;hashStruct(eip712Domain)&lt;&#x2F;code&gt;). This value does not suffice for the purposes of integrating with EIP-712, as the RPC methods defined there receive an object describing the domain and not just the separator in hash form. Note that this is not a flaw of the RPC methods, it is indeed part of the security proposition that the domain should be validated and informed to the user as part of the signing process. On its own, a hash does not allow this to be implemented, given it is opaque. The present EIP fills this gap in both EIP-712 and EIP-2612.&lt;&#x2F;p&gt;
&lt;p&gt;Extensions are described by their EIP numbers because EIP-712 states: &quot;Future extensions to this standard can add new fields [...] new fields should be proposed through the EIP process.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is an optional extension to EIP-712 that does not introduce backwards compatibility issues.&lt;&#x2F;p&gt;
&lt;p&gt;Upgradeable contracts that make use of EIP-712 signatures MAY be upgraded to implement this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;User-agents or applications that use this EIP SHOULD additionally support those contracts that due to their immutability cannot be upgraded to implement it. The simplest way to achieve this is to hardcode common domains based on contract address and chain id. However, it is also possible to implement a more general solution by guessing possible domains based on a few common patterns using the available information, and selecting the one whose hash matches a &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; or &lt;code&gt;domainSeparator&lt;&#x2F;code&gt; function in the contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;solidity-example&quot;&gt;Solidity Example&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP712VerifyingContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; eip712Domain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 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 class=&quot;z-support&quot;&gt;      bytes1&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; extensions&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&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 01101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;          &amp;quot;Example&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 class=&quot;z-string&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 class=&quot;z-variable z-language&quot;&gt;          block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;          new&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&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;This contract&#x27;s domain only uses the fields &lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;chainId&lt;&#x2F;code&gt;, and &lt;code&gt;verifyingContract&lt;&#x2F;code&gt;, therefore the &lt;code&gt;fields&lt;&#x2F;code&gt; value is &lt;code&gt;01101&lt;&#x2F;code&gt;, or &lt;code&gt;0d&lt;&#x2F;code&gt; in hexadecimal.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming this contract is on Ethereum mainnet and its address is 0x0000000000000000000000000000000000000001, the domain it describes is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-invalid z-illegal&quot;&gt;  n&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;e&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Example&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-invalid z-illegal&quot;&gt;  c&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;I&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;d&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-invalid z-illegal&quot;&gt;  v&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;h3 id=&quot;javascript&quot;&gt;JavaScript&lt;&#x2F;h3&gt;
&lt;p&gt;A domain object can be constructed based on the return values of an &lt;code&gt;eip712Domain()&lt;&#x2F;code&gt; invocation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the EIP-712 domain of a contract using EIP-5267 without extensions. &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; extensions&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;eip712Domain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;extensions&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Extensions not implemented&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; buildBasicDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; fieldNames&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;verifyingContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;salt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Builds a domain object without extensions based on the return values of `eip712Domain()`. &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; buildBasicDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; field&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; of&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fieldNames&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;entries&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fields&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; domain&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; domain&lt;&#x2F;span&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;h4 id=&quot;extensions&quot;&gt;Extensions&lt;&#x2F;h4&gt;
&lt;p&gt;Suppose EIP-XYZ defines a new field &lt;code&gt;subdomain&lt;&#x2F;code&gt; of type &lt;code&gt;bytes32&lt;&#x2F;code&gt; and a function &lt;code&gt;getSubdomain()&lt;&#x2F;code&gt; to retrieve its value.&lt;&#x2F;p&gt;
&lt;p&gt;The function &lt;code&gt;getDomain&lt;&#x2F;code&gt; from above would be extended as follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Retrieves the EIP-712 domain of a contract using EIP-5267 with support for EIP-XYZ. &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; extensions&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;eip712Domain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; buildBasicDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fields&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; verifyingContract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; of&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; extensions&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; XYZ&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;      domain&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getSubdomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;      throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; extension not implemented&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; domain&lt;&#x2F;span&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;Additionally, the type of the &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; struct needs to be extended with the &lt;code&gt;subdomain&lt;&#x2F;code&gt; field. This is left out of scope of this reference implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;While this EIP allows a contract to specify a &lt;code&gt;verifyingContract&lt;&#x2F;code&gt; other than itself, as well as a &lt;code&gt;chainId&lt;&#x2F;code&gt; other than that of the current chain, user-agents and applications should in general validate that these do match the contract and chain before requesting any user signatures for the domain. This may not always be a valid assumption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Contract Resource Requests</title>
        <published>2022-07-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5219/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/pr-5219-discussion-contract-rest/9907" />
        

        <id>https://wg-eips.ritovision.com/5219/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5219"
            label="ERC-5219" />
        

        
        

        
        <summary type="html">Allows the requesting of resources from contracts</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5219/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes an interface to make resource requests to smart contracts and to receive HTTP-like responses.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum is the most-established blockchain for building decentralized applications (referred to as &lt;code&gt;DApp&lt;&#x2F;code&gt;s). Due to this, the Ethereum DApp ecosystem is very diverse. However, one issue that plagues DApps is the fact that they are not fully decentralized. Specifically, to interface a &quot;decentralized&quot; application, one first needs to access a &lt;em&gt;centralized&lt;&#x2F;em&gt; website containing the DApp&#x27;s front-end code, presenting a few issues. The following are some risks associated with using centralized websites to interface with decentralized applications:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Trust Minimization: An unnecessarily large number of entities need to be trusted&lt;&#x2F;li&gt;
&lt;li&gt;Censorship: A centralized website is not resistant to being censored&lt;&#x2F;li&gt;
&lt;li&gt;Permanence: The interface may not have a mechanism that permits it to be permanently stored&lt;&#x2F;li&gt;
&lt;li&gt;Interoperability: Smart Contracts cannot directly interact with DApp interfaces&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;name-resolution&quot;&gt;Name Resolution&lt;&#x2F;h3&gt;
&lt;p&gt;EIPs that propose a name resolution mechanism MAY reference this EIP and MAY recommend that clients support their mechanism. Clients MAY also support regular DNS, as defined in RFC 1034 and RFC 1035.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;separation-of-concerns&quot;&gt;Separation of Concerns&lt;&#x2F;h3&gt;
&lt;p&gt;It is RECOMMENDED to separate the application logic from the front-end logic (the contract implementing the interface defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5219&#x2F;#contract-interface&quot;&gt;Contract Interface&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;p&gt;DApp contracts MUST implement the interface defined in the following file: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5219&#x2F;.&#x2F;assets&#x2F;IDecentralizedApp.sol&quot;&gt;Contract Interface&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;note-to-implementers&quot;&gt;Note to Implementers&lt;&#x2F;h3&gt;
&lt;p&gt;To save gas costs, it is recommended to use the &lt;code&gt;message&#x2F;external-body&lt;&#x2F;code&gt; MIME-type, which allows you to point to data that the smart contract might not have access to. For example, the following response would tell a client to fetch the data off of IPFS:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tatusCode&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ody&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HIS IS NOT REALLY THE BODY!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;eaders&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ey&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; C&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ontent-type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;alue&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;essage&#x2F;external-body; access-type=URL; URL=&amp;quot;ipfs:&#x2F;&#x2F;11148a173fd3e32c0fa78b90fe42d305f202244e2739&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;request&lt;&#x2F;code&gt; method was chosen to be readonly because all data should be sent to the contract from the parsed DApp. Here are some reasons why:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Submitting a transaction to send a request would be costly and would require waiting for the transaction to be mined, resulting in bad user experience.&lt;&#x2F;li&gt;
&lt;li&gt;Complicated front-end logic should not be stored in the smart contract, as it would be costly to deploy and would be better run on the end-user&#x27;s machine.&lt;&#x2F;li&gt;
&lt;li&gt;Separation of Concerns: the front-end contract shouldn&#x27;t have to worry about interacting with the back-end smart contract.&lt;&#x2F;li&gt;
&lt;li&gt;Other EIPs can be used to request state changing operations in conjunction with a &lt;code&gt;307 Temporary Redirect&lt;&#x2F;code&gt; status code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Instead of mimicking a full HTTP request, a highly slimmed version was chosen for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The only particularly relevant HTTP method is &lt;code&gt;GET&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Query parameters can be encoded in the resource.&lt;&#x2F;li&gt;
&lt;li&gt;Request headers are, for the most part, unnecessary for &lt;code&gt;GET&lt;&#x2F;code&gt; requests.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is backwards compatible with all standards listed in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5219&#x2F;#name-resolution&quot;&gt;Name Resolution&lt;&#x2F;a&gt; section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The normal security considerations of accessing normal URLs apply here, such as potential privacy leakage by following &lt;code&gt;3XX&lt;&#x2F;code&gt; redirects.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Minimal Soulbound NFTs</title>
        <published>2022-07-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Tim Daubenschütz</name><uri>https://github.com/TimDaub</uri>
	</author>
	
	<author>
		<name>Anders</name><uri>https://github.com/0xanders</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5192/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5192-minimal-soulbound-nfts/9814" />
        

        <id>https://wg-eips.ritovision.com/5192/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5192"
            label="ERC-5192" />
        

        
        

        
        <summary type="html">Minimal interface for soulbinding EIP-721 NFTs</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5192/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;. It proposes a minimal interface to make tokens soulbound using the feature detection functionality of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;. A soulbound token is a non-fungible token bound to a single account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The Ethereum community has expressed a need for non-transferrable, non-fungible, and socially-priced tokens similar to World of Warcraft’s soulbound items. But the lack of a token standard leads many developers to simply throw errors upon a user&#x27;s invocation of transfer functionalities. Over the long term, this will lead to fragmentation and less composability.&lt;&#x2F;p&gt;
&lt;p&gt;In this document, we outline a minimal addition to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; that allows wallet implementers to check for a token contract&#x27;s permanent (non-)transferability using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;p&gt;A token with a &lt;code&gt;uint256 tokenId&lt;&#x2F;code&gt; may be bound to a receiving account with &lt;code&gt;function locked(...)&lt;&#x2F;code&gt; returning &lt;code&gt;true&lt;&#x2F;code&gt;. In this case, all &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; functions of the contract that transfer the token from one account to another must throw.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5192&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the locking status is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to locked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If a token is minted and the status is locked, this event should be emitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Locked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the locking status is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to unlocked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If a token is minted and the status is unlocked, this event should be emitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Unlocked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the locking status of an Soulbound Token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SBTs assigned to zero address are considered invalid, and queries&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; about them do throw.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for an SBT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; locked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To aid recognition that an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; token implements &quot;soulbinding&quot; via this EIP upon calling &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;function supportsInterface(bytes4 interfaceID) external view returns (bool)&lt;&#x2F;code&gt; with &lt;code&gt;interfaceID=0xb45a3c0e&lt;&#x2F;code&gt;, a contract implementing this EIP must return &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The above model is the simplest possible path towards a canonical interface for Soulbound tokens. It reflects upon the numerous Soulbound token implementations that simply revert upon transfers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blueprint contract format</title>
        <published>2022-06-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Charles Cooper</name><uri>https://github.com/charles-cooper</uri>
	</author>
	
	<author>
		<name>Edward Amor</name><uri>https://github.com/skellet0r</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5202/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-5202-standard-factory-contract-format/9851" />
        

        <id>https://wg-eips.ritovision.com/5202/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5202"
            label="ERC-5202" />
        

        
        

        
        <summary type="html">Define a bytecode container format for indexing and utilizing blueprint contracts</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5202/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Define a standard for &quot;blueprint&quot; contracts, or contracts which represent initcode that is stored on-chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;To decrease deployer contract size, a useful pattern is to store initcode on chain as a &quot;blueprint&quot; contract, and then use &lt;code&gt;EXTCODECOPY&lt;&#x2F;code&gt; to copy the initcode into memory, followed by a call to &lt;code&gt;CREATE&lt;&#x2F;code&gt; or &lt;code&gt;CREATE2&lt;&#x2F;code&gt;. However, this comes with the following problems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is hard for external tools and indexers to detect if a contract is a &quot;regular&quot; runtime contract or a &quot;blueprint&quot; contract. Heuristically searching for patterns in bytecode to determine if it is initcode poses maintenance and correctness problems.&lt;&#x2F;li&gt;
&lt;li&gt;Storing initcode byte-for-byte on-chain is a correctness and security problem. Since the EVM does not have a native way to distinguish between executable code and other types of code, unless the initcode explicitly implements ACL rules, &lt;em&gt;anybody&lt;&#x2F;em&gt; can call such a &quot;blueprint&quot; contract and execute the initcode directly as ordinary runtime code. This is particularly problematic if the initcode stored by the blueprint contract has side effects such as writing to storage or calling external contracts. If the initcode stored by the blueprint contract executes a &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; opcode, the blueprint contract could even be removed, preventing the correct operation of downstream deployer contracts that rely on the blueprint existing. For this reason, it would be good to prefix blueprint contracts with a special preamble to prevent execution.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;A blueprint contract MUST use the preamble &lt;code&gt;0xFE71&amp;lt;version bits&amp;gt;&amp;lt;length encoding bits&amp;gt;&lt;&#x2F;code&gt;. 6 bits are allocated to the version, and 2 bits to the length encoding. The first version begins at 0 (&lt;code&gt;0b000000&lt;&#x2F;code&gt;), and versions increment by 1. The value &lt;code&gt;0b11&lt;&#x2F;code&gt; for &lt;code&gt;&amp;lt;length encoding bits&amp;gt;&lt;&#x2F;code&gt; is reserved. In the case that the length bits are &lt;code&gt;0b11&lt;&#x2F;code&gt;, the third byte is considered a continuation byte (that is, the version requires multiple bytes to encode). The exact encoding of a multi-byte version is left to a future ERC.&lt;&#x2F;p&gt;
&lt;p&gt;A blueprint contract MUST contain at least one byte of initcode.&lt;&#x2F;p&gt;
&lt;p&gt;A blueprint contract MAY insert any bytes (data or code) between the version byte(s) and the initcode. If such variable length data is used, the preamble must be &lt;code&gt;0xFE71&amp;lt;version bits&amp;gt;&amp;lt;length encoding bits&amp;gt;&amp;lt;length bytes&amp;gt;&amp;lt;data&amp;gt;&lt;&#x2F;code&gt;. The &lt;code&gt;&amp;lt;length encoding bits&amp;gt;&lt;&#x2F;code&gt; represent a number between 0 and 2 (inclusive) describing how many bytes &lt;code&gt;&amp;lt;length bytes&amp;gt;&lt;&#x2F;code&gt; takes, and &lt;code&gt;&amp;lt;length bytes&amp;gt;&lt;&#x2F;code&gt; is the big-endian encoding of the number of bytes that &lt;code&gt;&amp;lt;data&amp;gt;&lt;&#x2F;code&gt; takes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To save gas and storage space, the preamble should be as minimal as possible.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It is considered &quot;bad&quot; behavior to try to CALL a blueprint contract directly, therefore the preamble starts with &lt;code&gt;INVALID (0xfe)&lt;&#x2F;code&gt; to end execution with an exceptional halting condition (rather than a &quot;gentler&quot; opcode like &lt;code&gt;STOP (0x00)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To help distinguish a blueprint contract from other contracts that may start with &lt;code&gt;0xFE&lt;&#x2F;code&gt;, a &quot;magic&quot; byte is used. The value &lt;code&gt;0x71&lt;&#x2F;code&gt; was arbitrarily chosen by taking the last byte of the keccak256 hash of the bytestring &quot;blueprint&quot; (i.e.: &lt;code&gt;keccak256(b&quot;blueprint&quot;)[-1]&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;An empty initcode is disallowed by the spec to prevent what might be a common mistake.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Users may want to include arbitrary data or code in their preamble. To allow indexers to ignore these bytes, a variable length encoding is proposed. To allow the length to be only zero or one bytes (in the presumably common case that &lt;code&gt;len(data bytes)&lt;&#x2F;code&gt; is smaller than 256), two bits of the third byte are reserved to specify how many bytes the encoded length takes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In case we need an upgrade path, version bits are included. While we do not expect to exhaust the version bits, in case we do, a continuation sequence is reserved. Since only two bytes are required for &lt;code&gt;&amp;lt;length bytes&amp;gt;&lt;&#x2F;code&gt; (as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;170&#x2F;&quot;&gt;EIP-170&lt;&#x2F;a&gt; restricts contract length to 24KB), a &lt;code&gt;&amp;lt;length encoding bits&amp;gt;&lt;&#x2F;code&gt; value of 3 would never be required to describe &lt;code&gt;&amp;lt;length bytes&amp;gt;&lt;&#x2F;code&gt;. For that reason, the special &lt;code&gt;&amp;lt;length encoding bits&amp;gt;&lt;&#x2F;code&gt; value of &lt;code&gt;0b11&lt;&#x2F;code&gt; is reserved as a continuation sequence marker.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The length of the initcode itself is not included by default in the preamble because it takes space, and it can be trivially determined using &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Ethereum Object Format (EOF) could provide another way of specifying blueprint contracts, by adding another section kind (3 - initcode). However, it is not yet in the EVM, and we would like to be able to standardize blueprint contracts today, without relying on EVM changes. If, at some future point, section kind 3 becomes part of the EOF spec, and the EOF becomes part of the EVM, this ERC will be considered to be obsolesced since the EOF validation spec provides much stronger guarantees than this ERC.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No known issues&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;An example (and trivial!) blueprint contract with no data section, whose initcode is just the &lt;code&gt;STOP&lt;&#x2F;code&gt; instruction:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xFE710000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;An example blueprint contract whose initcode is the trivial &lt;code&gt;STOP&lt;&#x2F;code&gt; instruction and whose data section contains the byte &lt;code&gt;0xFF&lt;&#x2F;code&gt; repeated seven times:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xFE710107FFFFFFFFFFFFFF00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, 0xFE71 is the magic header, &lt;code&gt;0x01&lt;&#x2F;code&gt; means version 0 + 1 length bit, &lt;code&gt;0x07&lt;&#x2F;code&gt; encodes the length in bytes of the data section. These are followed by the data section, and then the initcode. For illustration, the above code with delimiters would be &lt;code&gt;0xFE71|01|07|FFFFFFFFFFFFFF|00&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An example blueprint whose initcode is the trivial &lt;code&gt;STOP&lt;&#x2F;code&gt; instruction and whose data section contains the byte &lt;code&gt;0xFF&lt;&#x2F;code&gt; repeated 256 times:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xFE71020100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Delimited, that would be &lt;code&gt;0xFE71|02|0100|FF...FF|00&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Optional&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Tuple&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; parse_blueprint_preamble&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;bytecode&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Optional&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Given bytecode as a sequence of bytes, parse the blueprint preamble and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    deconstruct the bytecode into:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        the ERC version, preamble data and initcode.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Raises an exception if the bytecode is not a valid blueprint contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    according to this ERC.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    arguments:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        bytecode: a `bytes` object representing the bytecode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        (version,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;         None if &amp;lt;length encoding bits&amp;gt; is 0, otherwise the bytes of the data section,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;         the bytes of the initcode,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\xFE&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x71&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not a blueprint!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    erc_version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0b&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;11111100&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&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;    n_length_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0b&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; n_length_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0b&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Reserved bits are set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data_length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; n_length_bytes&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; byteorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; n_length_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        preamble_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;        data_start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; n_length_bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        preamble_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;data_start&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;data_start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; data_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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    initcode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytecode&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; n_length_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; data_length&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;initcode&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Empty initcode!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; erc_version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; preamble_data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; initcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The following reference function takes the desired initcode for a blueprint as a parameter, and returns EVM code which will deploy a corresponding blueprint contract (with no data section):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; blueprint_deployer_bytecode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;initcode&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blueprint_preamble&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\xFE&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x71&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC5202 preamble&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blueprint_bytecode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blueprint_preamble&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; initcode&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the length of the deployed code in bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    len_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;blueprint_bytecode&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;big&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; copy &amp;lt;blueprint_bytecode&amp;gt; to memory and `RETURN` it per EVM creation semantics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; PUSH2 &amp;lt;len&amp;gt; RETURNDATASIZE DUP2 PUSH1 10 RETURNDATASIZE CODECOPY RETURN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deploy_bytecode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x61&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; len_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x3d&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x81&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x60&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x0a&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x3d&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\x39&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\xf3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; deploy_bytecode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; blueprint_bytecode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There could be contracts on-chain already which happen to start with the same prefix as proposed in this ERC. However, this is not considered a serious risk, because the way it is envisioned that indexers will use this is to verify source code by compiling it and prepending the preamble.&lt;&#x2F;p&gt;
&lt;p&gt;As of 2022-07-08, no contracts deployed on the Ethereum mainnet have a bytecode starting with &lt;code&gt;0xFE71&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Delaying Difficulty Bomb to mid-September 2022</title>
        <published>2022-06-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tomasz Kajetan Stanczak</name><uri>https://github.com/tkstanczak</uri>
	</author>
	
	<author>
		<name>Eric Marti Haynes</name><uri>https://github.com/ericmartihaynes</uri>
	</author>
	
	<author>
		<name>Josh Klopfenstein</name><uri>https://github.com/joshklop</uri>
	</author>
	
	<author>
		<name>Abhimanyu Nag</name><uri>https://github.com/AbhiMan1601</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5133/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5133-delaying-difficulty-bomb-to-mid-september-2022/9622" />
        

        <id>https://wg-eips.ritovision.com/5133/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5133"
            label="EIP-5133" />
        

        
        

        
        <summary type="html">Delays the difficulty bomb by a further 700000 blocks, to the middle of September 2022.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5133/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 11,400,000 blocks later than the actual block number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;To avoid network degradation due to a premature activation of the difficulty bomb.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fake_block_number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11_400_000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The following script predicts the bomb will go off at block 15530314, which is expected to be mined around mid-September.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; math&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; predict_bomb_block&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;current_difficulty&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block_adjustment&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Predicts the block number at which the difficulty bomb will become noticeable.&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 class=&quot;z-string&quot;&gt;    current_difficulty: the current difficulty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    diff_adjust_coeff: intuitively, the percent increase in work that miners have to exert to find a PoW&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    block_adjustment: the number of blocks to delay the bomb by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; round&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block_adjustment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;log2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; current_difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2048&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; current_difficulty = 13891609586928851 (Jun 01, 2022)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; diff_adjust_coeff = 0.1 (historically, the bomb is noticeable when the coefficient is &amp;gt;= 0.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block_adjustment = 11400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;predict_bomb_block&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;13891609586928851&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11400000&lt;&#x2F;span&gt;&lt;span&gt;)&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;Precise increases in block times are very difficult to predict (especially after the bomb is noticeable).
However, based on past manifestations of the bomb, we can anticipate 0.1s delays by mid-September and 0.6-1.2s delays by early October.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No known backward compatibility issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Misjudging the effects of the difficulty can mean longer blocktimes than anticipated until a hardfork is released. Wild shifts in difficulty can affect this number severely. Also, gradual changes in blocktimes due to longer-term adjustments in difficulty can affect the timing of difficulty bomb epochs. This affects the usability of the network but unlikely to have security ramifications.&lt;&#x2F;p&gt;
&lt;p&gt;In this specific instance, it is possible that the network hashrate drops considerably before The Merge, which could accelerate the timeline by which the bomb is felt in block times. The offset value chosen aims to take this into account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Client Script URI for Token Contracts</title>
        <published>2022-05-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>James</name><uri>https://github.com/JamesSmartCell</uri>
	</author>
	
	<author>
		<name>Weiwu</name><uri>https://github.com/weiwu-zhang</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5169/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5169-client-script-uri-for-token-contracts/9674" />
        

        <id>https://wg-eips.ritovision.com/5169/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5169"
            label="ERC-5169" />
        

        
        

        
        <summary type="html">Add a scriptURI to point to an executable script associated with the functionality of the token.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5169/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP provides a contract interface adding a &lt;code&gt;scriptURI()&lt;&#x2F;code&gt; function for locating executable scripts associated with the token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Often, smart contract authors want to provide some user functionality to their tokens through client scripts. The idea is made popular with function-rich NFTs. It&#x27;s important that a token&#x27;s contract is linked to its client script, since the client script may carry out trusted tasks such as creating transactions for the user.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP allows users to be sure they are using the correct script through the contract by providing a URI to an official script, made available with a call to the token contract itself (&lt;code&gt;scriptURI&lt;&#x2F;code&gt;). This URI can be any RFC 3986-compliant URI, such as a link to an IPFS multihash, GitHub gist, or a cloud storage provider. Each contract implementing this EIP  implements a &lt;code&gt;scriptURI&lt;&#x2F;code&gt; function which returns the download URI to a client script. The script provides a client-side executable to the hosting token. Examples of such a script could be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A &#x27;miniDapp&#x27;, which is a cut-down DApp tailored for a single token.&lt;&#x2F;li&gt;
&lt;li&gt;A &#x27;TokenScript&#x27; which provides TIPS from a browser wallet.&lt;&#x2F;li&gt;
&lt;li&gt;A &#x27;TokenScript&#x27; that allows users to interact with contract functions not normally provided by a wallet, eg &#x27;mint&#x27; function.&lt;&#x2F;li&gt;
&lt;li&gt;An extension that is downloadable to the hardware wallet with an extension framework, such as Ledger.&lt;&#x2F;li&gt;
&lt;li&gt;JavaScript instructions to operate a smartlock, after owner receives authorization token in their wallet.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;With the discussion above in mind, we outline the solution proposed by this EIP. For this purpose, we consider the following variables:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;SCPrivKey&lt;&#x2F;code&gt;: The private signing key to administrate a smart contract implementing this EIP. Note that this doesn&#x27;t have to be a new key especially added for this EIP. Most smart contracts made today already have an administration key to manage the tokens issued. It can be used to update the &lt;code&gt;scriptURI&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;newScriptURI&lt;&#x2F;code&gt;: an array of URIs for different ways to find the client script.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can describe the life cycle of the &lt;code&gt;scriptURI&lt;&#x2F;code&gt; functionality:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Issuance&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;The token issuer issues the tokens and a smart contract implementing this EIP, with the admin key for the smart contract being &lt;code&gt;SCPrivKey&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The token issuer calls &lt;code&gt;setScriptURI&lt;&#x2F;code&gt; with the &lt;code&gt;scriptURI&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;scriptURI&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;The token issuer stores the desired &lt;code&gt;script&lt;&#x2F;code&gt; at all the new URI locations and constructs a new &lt;code&gt;scriptURI&lt;&#x2F;code&gt; structure based on this.&lt;&#x2F;li&gt;
&lt;li&gt;The token issuer calls &lt;code&gt;setScriptURI&lt;&#x2F;code&gt; with the new &lt;code&gt;scriptURI&lt;&#x2F;code&gt; structure.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;We define a scriptURI element using the &lt;code&gt;string[]&lt;&#x2F;code&gt;.
Based on this, we define the smart contract interface below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5169&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when the scriptURI is updated, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; so wallets implementing this interface can update a cached script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ScriptUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newScriptURI&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the scriptURI for the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; scriptURI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; scriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Update the scriptURI &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; emits event ScriptUpdate(scriptURI memory newScriptURI);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setScriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newScriptURI&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interface MUST be implemented under the following constraints:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The smart contract implementing &lt;code&gt;IERC5169&lt;&#x2F;code&gt; MUST store variables &lt;code&gt;address owner&lt;&#x2F;code&gt; in its state.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The smart contract implementing &lt;code&gt;IERC5169&lt;&#x2F;code&gt; MUST set &lt;code&gt;owner=msg.sender&lt;&#x2F;code&gt; in its constructor.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;ScriptUpdate(...)&lt;&#x2F;code&gt; event MUST be emitted when the &lt;code&gt;setScriptURI&lt;&#x2F;code&gt; function updates the &lt;code&gt;scriptURI&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;setScriptURI(...)&lt;&#x2F;code&gt; function MUST validate that &lt;code&gt;owner == msg.sender&lt;&#x2F;code&gt; &lt;em&gt;before&lt;&#x2F;em&gt; executing its logic and updating any state.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;setScriptURI(...)&lt;&#x2F;code&gt; function MUST update its internal state such that &lt;code&gt;currentScriptURI = newScriptURI&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;scriptURI()&lt;&#x2F;code&gt; function MUST return the &lt;code&gt;currentScriptURI&lt;&#x2F;code&gt; state.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;scriptURI()&lt;&#x2F;code&gt; function MAY be implemented as pure or view.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any user of the script learned from &lt;code&gt;scriptURI&lt;&#x2F;code&gt; MUST validate the script is either at an immutable location, its URI contains its hash digest, or it implements the separate &lt;code&gt;Authenticity for Client Script&lt;&#x2F;code&gt; EIP, which asserts authenticity using signatures instead of a digest.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This method avoids the need for building secure and certified centralized hosting and allows scripts to be hosted anywhere: IPFS, GitHub or cloud storage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is backwards-compatible with most existing token standards, including the following commonly-used ones:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;test-contract&quot;&gt;Test Contract&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;access&#x2F;Ownable.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC5169.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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5169&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5169&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _scriptURI&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; scriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _scriptURI&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setScriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newScriptURI&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        _scriptURI &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newScriptURI&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ScriptUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newScriptURI&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;test-cases-1&quot;&gt;Test Cases&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chai&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; BigNumber&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; Wallet&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ethers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ethers&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; network&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; getChainId&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hardhat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;describe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC5169&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;  before&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;ERC5169&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ethers&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getContractFactory&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC5169&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  beforeEach&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; targetNFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc5169&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;ERC5169&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;deploy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Should set script URI&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; scriptURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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&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 class=&quot;z-keyword&quot;&gt;    await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc5169&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;setScriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;scriptURI&lt;&#x2F;span&gt;&lt;span&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&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;emit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc5169&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ScriptUpdate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;withArgs&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;scriptURI&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; currentScriptURI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;erc5169&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;scriptURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;currentScriptURI&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;scriptURI&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;An intuitive implementation is the STL office door token. This NFT is minted and transferred to STL employees. The TokenScript attached to the token contract via the &lt;code&gt;scriptURI()&lt;&#x2F;code&gt; function contains instructions on how to operate the door interface. This takes the form of:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Query for challenge string (random message from IoT interface eg &#x27;Apples-5E3FA1&#x27;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Receive and display challenge string on Token View, and request &#x27;Sign Personal&#x27;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;On obtaining the signature of the challenge string, send back to IoT device.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;IoT device will unlock door if ec-recovered address holds the NFT.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;With &lt;code&gt;scriptURI()&lt;&#x2F;code&gt; the experience is greatly enhanced as the flow for the user is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Receive NFT.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use authenticated NFT functionality in the wallet immediately.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The project with contract, TokenScript and IoT firmware is in use by Smart Token Labs office door and numerous other installations. An example implementation contract: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5169&#x2F;.&#x2F;assets&#x2F;contract&#x2F;ExampleContract.sol&quot;&gt;ERC-5169 Contract Example&lt;&#x2F;a&gt; and TokenScript:  &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5169&#x2F;.&#x2F;assets&#x2F;tokenscript&#x2F;ExampleScript.xml&quot;&gt;ERC-5169 TokenScript Example&lt;&#x2F;a&gt;. Links to the firmware and full sample can be found in the associated discussion linked in the header.
The associated TokenScript can be read from the contract using &lt;code&gt;scriptURI()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;script-location&quot;&gt;Script location&lt;&#x2F;h3&gt;
&lt;p&gt;While the most straightforward solution to facilitate specific script usage associated with NFTs, is clearly to store such a script on the smart contract. However, this has several disadvantages:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The smart contract signing key is needed to make updates, causing the key to become more exposed, as it is used more often.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Updates require smart contract interaction. If frequent updates are needed, smart contract calls can become an expensive hurdle.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Storage fee. If the script is large, updates to the script will be costly. A client script is typically much larger than a smart contract.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For these reasons, storing volatile data, such as token enhancing functionality, on an external resource makes sense. Such an external resource can be either be  hosted centrally, such as through a cloud provider, or privately hosted through a private server, or decentralized hosted, such as the interplanetary filesystem.&lt;&#x2F;p&gt;
&lt;p&gt;While centralized storage for a decentralized functionality goes against the ethos of web3, fully decentralized solutions may come with speed, price or space penalties. This EIP handles this by allowing the function &lt;code&gt;ScriptURI&lt;&#x2F;code&gt; to return multiple URIs, which could be a mix of centralized, individually hosted and decentralized locations.&lt;&#x2F;p&gt;
&lt;p&gt;While this EIP does not dictate the format of the stored script, the script itself could contain pointers to multiple other scripts and data sources, allowing for advanced ways to expand token scripts, such as lazy loading.
The handling of integrity of such secondary data sources is left dependent on the format of the script.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;When a server is involved&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When the client script does not purely rely on connection to a blockchain node, but also calls server APIs,  the trustworthiness of the server API is called into question. This EIP does not provide any mechanism to assert the authenticity of the API access point. Instead, as long as the client script is trusted, it&#x27;s assumed that it can call any server API in order to carry out token functions. This means the client script can mistrust a server API access point.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When the scriptURI doesn&#x27;t contain integrity (hash) information&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We separately authored &lt;code&gt;Authenticity for Client Script&lt;&#x2F;code&gt; EIP to guide on how to use digital signatures efficiently and concisely to ensure authenticity and integrity of scripts not stored at a URI which is a digest of the script itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Time NFT, ERC-721 Time Extension</title>
        <published>2022-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Anders</name><uri>https://github.com/0xanders</uri>
	</author>
	
	<author>
		<name>Lance</name><uri>https://github.com/LanceSnow</uri>
	</author>
	
	<author>
		<name>Shrug</name><email>shrug@emojidao.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5007/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5007-eip-721-time-extension/8924" />
        

        <id>https://wg-eips.ritovision.com/5007/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:5007"
            label="ERC-5007" />
        

        
        

        
        <summary type="html">Add start time and end time to ERC-721 tokens.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5007/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;. It proposes some additional functions (&lt;code&gt;startTime&lt;&#x2F;code&gt;, &lt;code&gt;endTime&lt;&#x2F;code&gt;) to help with on-chain time management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Some NFTs have a defined usage period and cannot be used outside of that period. With traditional NFTs that do not include time information, if you want to mark a token as invalid or enable it at a specific time, you need to actively submit a transaction—a process both cumbersome and expensive.&lt;&#x2F;p&gt;
&lt;p&gt;Some existing NFTs contain time functions, but their interfaces are not consistent, so it is difficult to develop third-party platforms for them.&lt;&#x2F;p&gt;
&lt;p&gt;By introducing these functions (&lt;code&gt;startTime&lt;&#x2F;code&gt;, &lt;code&gt;endTime&lt;&#x2F;code&gt;), it is possible to enable and disable NFTs automatically on chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the ERC-165 identifier for this interface is 0xf140be0d.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5007&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the start time of the NFT as a UNIX timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; startTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the end time of the NFT as a UNIX timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; endTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&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;&#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 &lt;strong&gt;composable extension&lt;&#x2F;strong&gt; is OPTIONAL for this standard. This allows your NFT to be minted from an existing NFT or to merge two NFTs into one NFT.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the ERC-165 identifier for this interface is 0x75cf3842.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5007Composable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC5007 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the asset id of the time NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Only NFTs with same asset id can be merged.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `tokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Split an old token to two new tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The assetId of the new token is the same as the assetId of the old token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `oldTokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newToken1Id` must not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newToken1Owner` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newToken2Id` must not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newToken2Owner` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `splitTime`  require(oldToken.startTime &amp;lt;= splitTime &amp;amp;&amp;amp; splitTime &amp;lt; oldToken.EndTime)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newToken1Id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newToken1Owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newToken2Id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newToken2Owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; splitTime&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Merge the first token and second token into the new token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `firstTokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `secondTokenId` must exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - require((firstToken.endTime + 1) == secondToken.startTime)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - require((firstToken.assetId()) == secondToken.assetId())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newTokenOwner` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `newTokenId` must not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; merge&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; firstTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; secondTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newTokenOwner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newTokenId&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;time-data-type&quot;&gt;Time Data Type&lt;&#x2F;h3&gt;
&lt;p&gt;The max value of &lt;code&gt;uint64&lt;&#x2F;code&gt; is 18,446,744,073,709,551,615. As a timestamp, 18,446,744,073,709,551,615 is about year 584,942,419,325. &lt;code&gt;uint256&lt;&#x2F;code&gt; is too big for C, C++, Java, Go, etc, and &lt;code&gt;uint64&lt;&#x2F;code&gt; is natively supported by mainstream programming languages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is fully ERC-721 compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5007&#x2F;.&#x2F;assets&#x2F;test&#x2F;test.js&quot;&gt;test.js&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Run in terminal:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..&#x2F;assets&#x2F;eip-5007&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; truffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;truffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5007&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC5007.sol&quot;&gt;&lt;code&gt;ERC5007.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security issues found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Rental NFT, NFT User Extension</title>
        <published>2022-04-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Lance</name><uri>https://github.com/LanceSnow</uri>
	</author>
	
	<author>
		<name>Anders</name><uri>https://github.com/0xanders</uri>
	</author>
	
	<author>
		<name>Shrug</name><email>shrug@emojidao.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5006/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip5006-erc-1155-usage-rights-extension/8941" />
        

        <id>https://wg-eips.ritovision.com/5006/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:5006"
            label="ERC-5006" />
        

        
        

        
        <summary type="html">Add a user role with restricted permissions to ERC-1155 tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5006/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;. It proposes an additional role (&lt;code&gt;user&lt;&#x2F;code&gt;) which can be granted to addresses that represent a &lt;code&gt;user&lt;&#x2F;code&gt; of the assets rather than an &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; tokens may have utility of some kind. The people who “use” the token may be different than the people who own it (such as in a rental). Thus, it would be useful to have separate roles for the “owner” and the “user” so that the “user” would not be able to take actions that the owner could (for example, transferring ownership).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&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 class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5006&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UserRecord&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; expiry&lt;&#x2F;span&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when permission for `user` to use `amount` of `tokenId` token owned by `owner`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * until `expiry` are given.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CreateUserRecord&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recordId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;  expiry&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when record of `recordId` are deleted. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DeleteUserRecord&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recordId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the usable amount of `tokenId` tokens  by `account`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; usableBalanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the amount of frozen tokens of token type `id` by `account`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; frozenBalanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the `UserRecord` of `recordId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userRecordOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recordId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;UserRecord&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gives permission to `user` to use `amount` of `tokenId` token owned by `owner` until `expiry`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits a {CreateUserRecord} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - If the caller is not `owner`, it must be have been approved to spend ``owner``&amp;#39;s tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * via {setApprovalForAll}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `owner` must have a balance of tokens of type `id` of at least `amount`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `user` cannot be the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `amount` must be greater than 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - `expiry` must after the block timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createUserRecord&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expiry&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Atomically delete `record` of `recordId` by the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits a {DeleteUserRecord} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Requirements:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * - the caller must have allowance.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; deleteUserRecord&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recordId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0xc26d96cc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This model is intended to facilitate easy implementation. The following are some problems that are solved by this standard:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;clear-rights-assignment&quot;&gt;Clear Rights Assignment&lt;&#x2F;h3&gt;
&lt;p&gt;With Dual “owner” and “user” roles, it becomes significantly easier to manage what lenders and borrowers can and cannot do with the NFT (in other words, their rights).  For example, for the right to transfer ownership, the project simply needs to check whether the address taking the action represents the owner or the user and prevent the transaction if it is the user.  Additionally, owners can control who the user is and it is easy for other projects to assign their own rights to either the owners or the users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;easy-third-party-integration&quot;&gt;Easy Third-Party Integration&lt;&#x2F;h3&gt;
&lt;p&gt;In the spirit of permissionless interoperability, this standard makes it easier for third-party protocols to manage NFT usage rights without permission from the NFT issuer or the NFT application. Once a project has adopted the additional &lt;code&gt;user&lt;&#x2F;code&gt; role, any other project can directly interact with these features and implement their own type of transaction. For example, a PFP NFT using this standard can be integrated into both a rental platform where users can rent the NFT for 30 days AND, at the same time, a mortgage platform where users can use the NFT while eventually buying ownership of the NFT with installment payments. This would all be done without needing the permission of the original PFP project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the specifications section, this standard can be fully ERC compatible by adding an extension function set, and there are no conflicts between &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5006&#x2F;&quot;&gt;ERC-5006&lt;&#x2F;a&gt; and ERC-1155.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, new functions introduced in this standard have many similarities with the existing functions in ERC-1155. This allows developers to easily adopt the standard quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5006&#x2F;.&#x2F;assets&#x2F;test&#x2F;test.ts&quot;&gt;test.js&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Run in terminal:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;cd ..&#x2F;assets&#x2F;eip-5006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;npm install&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;npx hardhat test&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5006&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC5006.sol&quot;&gt;&lt;code&gt;ERC5006.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standard can completely protect the rights of the owner, the owner can change the NFT user, the user can not transfer the NFT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Vendor Metadata Extension for NFTs</title>
        <published>2022-03-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ignacio Mazzara</name><uri>https://github.com/nachomazzara</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4955/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4955-non-fungible-token-metadata-namespaces-extension/8746" />
        

        <id>https://wg-eips.ritovision.com/4955/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:4955"
            label="ERC-4955" />
        

        
        

        
        <summary type="html">Add a new field to NFT metadata to store vendor specific data</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4955/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes a schema for NFTs metadata to add new field namespaces to the JSON schema for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; NFTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A standardized NFT metadata schema allows wallets, marketplaces, metaverses, and similar applications to interoperate with any NFT. Applications such as NFT marketplaces and metaverses could usefully leverage NFTs by rendering them using custom 3D representations or any other new attributes.&lt;&#x2F;p&gt;
&lt;p&gt;Some projects like Decentraland, TheSandbox, Cryptoavatars, etc. need their own 3D model in order to represent an NFT. These models are not cross-compatible because of distinct aesthetics and data formats.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;schema&quot;&gt;Schema&lt;&#x2F;h3&gt;
&lt;p&gt;(subject to &quot;caveats&quot; below)&lt;&#x2F;p&gt;
&lt;p&gt;A new property called &lt;code&gt;namespaces&lt;&#x2F;code&gt; is introduced. This property expects one object per project as shown in the example below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;jsonc&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset that this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset that this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset that this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Application-specific NFT properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;jsonc&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;My NFT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;NFT description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ipfs:&#x2F;&#x2F;QmZfmRZHuawJDtDVMaEaPWfgWFV9iXoS9SzLvwX76wm6pa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;myAwesomeCompany&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prop1&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prop2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;myAwesomeCompany2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prop3&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;prop4&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Or by simply using a `URI` to reduce the size of the JSON response.&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;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;My NFT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;NFT description&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ipfs:&#x2F;&#x2F;QmZfmRZHuawJDtDVMaEaPWfgWFV9iXoS9SzLvwX76wm6pa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;myAwesomeCompany&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URI&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;myAwesomeCompany2&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URI&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;There are many projects which need custom properties in order to display a current NFT. Each project may have its own way to render the NFTs and therefore they need different values. An example of this is the metaverses like Decentraland or TheSandbox where they need different 3d models to render the NFT based on the visual&#x2F;engine of each. NFTs projects like Cryptopunks, Bored Apes, etc. can create the 3d models needed for each project and therefore be supported out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;The main differences between the projects that are rendering 3d NFTs (models) are:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;armatures&quot;&gt;Armatures&lt;&#x2F;h3&gt;
&lt;p&gt;Every metaverse uses its own armature. There is a standard for humanoids but it is not being used for every metaverse and not all the metaverses use humanoids. For example, Decentraland has a different aesthetic than Cryptovoxels and TheSandbox. It means that every metaverse will need a different model and they may have the same extension (GLB, GLTF)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4955&#x2F;.&#x2F;assets&#x2F;different-renders.jpeg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;metadata-representations-files&quot;&gt;Metadata (Representations Files)&lt;&#x2F;h3&gt;
&lt;p&gt;For example, every metaverse uses its own metadata representation files to make it work inside the engine depending on its game needs.&lt;&#x2F;p&gt;
&lt;p&gt;This is the JSON config of a wearable item in Decentraland:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;jsonc&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;replaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hides&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;category&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;upper_body&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;representations&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bodyShapes&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;urn:decentraland:off-chain:base-avatars:BaseMale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;mainFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;male&#x2F;Look6_Tshirt_A.glb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contents&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;male&#x2F;Look6_Tshirt_A.glb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;peer-ec2.decentraland.org&#x2F;content&#x2F;contents&#x2F;QmX3yMhmx4AvGmyF3CM5ycSQB4F99zXh9rL5GvdxTTcoCR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;overrideHides&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;overrideReplaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bodyShapes&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;urn:decentraland:off-chain:base-avatars:BaseFemale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;mainFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;female&#x2F;Look6_Tshirt_B (1).glb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contents&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;female&#x2F;Look6_Tshirt_B (1).glb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;peer-ec2.decentraland.org&#x2F;content&#x2F;contents&#x2F;QmcgddP4L8CEKfpJ4cSZhswKownnYnpwEP4eYgTxmFdav8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;overrideHides&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;overrideReplaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;peer-ec2.decentraland.org&#x2F;content&#x2F;contents&#x2F;QmPnzQZWAMP4Grnq6phVteLzHeNxdmbRhKuFKqhHyVMqrK&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thumbnail&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;peer-ec2.decentraland.org&#x2F;content&#x2F;contents&#x2F;QmcnBFjhyFShGo9gWk2ETbMRDudiX7yjn282djYCAjoMuL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;metrics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;triangles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3400&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;materials&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;textures&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;meshes&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bodies&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;entities&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&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;&lt;code&gt;replaces&lt;&#x2F;code&gt;, &lt;code&gt;overrides&lt;&#x2F;code&gt;, &lt;code&gt;hides&lt;&#x2F;code&gt;, and different body shapes representation for the same asset are needed for Decentraland in order to render the 3D asset correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Using &lt;code&gt;namespaces&lt;&#x2F;code&gt; instead of objects like the ones below make it easy for the specific vendor&#x2F;third-parties to access and index the required models. Moreover, &lt;code&gt;styles&lt;&#x2F;code&gt; do not exist because there are no standards around for how an asset will be rendered. As I mentioned above, each metaverse for example uses its own armature and aesthetic. There is no Decentraland-style or TheSandbox-style that other metaverses use. Each of them is unique and specific for the sake of the platform&#x27;s reason of being. Projects like Cryptoavatars are trying to push different standards but without luck for the same reasons related to the uniquity of the armature&#x2F;animations&#x2F;metadata.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;jsonc&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;model&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;model&#x2F;gltf+json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;style&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Decentraland&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Or&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;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;model&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;model&#x2F;gltf+json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;style&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;humanoide&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With &lt;code&gt;namespaces&lt;&#x2F;code&gt;, each vendor will know how to render an asset by doing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;fetch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;namespaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PROJECT_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;res&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; render&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;res&lt;&#x2F;span&gt;&lt;span&gt;)&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 idea behind extending the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; metadata schema is for backward compatibility. Most projects on Ethereum use non-upgradeable contracts. If this EIP required new implementations of those contracts, they would have to be re-deployed. This is time-consuming and wastes money. Leveraging EIP-721&#x27;s existing metadata  field minimizes the number of changes necessary. Finally, the JSON metadata is already used to store representations using the &lt;code&gt;image&lt;&#x2F;code&gt; field. It seems reasonable to have all the representations of an asset in the same place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Existing projects that can&#x27;t modify the metadata response (schema), may be able to create a new smart contract that based on the &lt;code&gt;tokenId&lt;&#x2F;code&gt; returns the updated metadata schema. Of course, the projects may need to accept these linked smart contracts as valid in order to fetch the metadata by the &lt;code&gt;tokenURI&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The same security considerations as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; apply related to using http gateways or IPFS for the tokenURI method.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;eth&#x2F;67 - Removal of GetNodeData&quot;</title>
        <published>2022-03-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	<author>
		<name>Felix Lange</name><email>fjl@ethereum.org</email>
	</author>
	
	<author>
		<name>Gary Rong</name><email>garyrong@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4938/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4938-removal-of-getnodedata/8893" />
        

        <id>https://wg-eips.ritovision.com/4938/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4938"
            label="EIP-4938" />
        

        
        

        
        <summary type="html">&quot;Remove GetNodeData and NodeData messages from the wire protocol&quot;</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4938/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;eth.md&quot;&gt;Ethereum Wire Protocol&lt;&#x2F;a&gt; defines request and response messages for exchanging data between clients. The &lt;code&gt;GetNodeData&lt;&#x2F;code&gt; request retrieves a set of trie nodes or contract code from the state trie by hash. We propose to remove the &lt;code&gt;GetNodeData&lt;&#x2F;code&gt; and &lt;code&gt;NodeData&lt;&#x2F;code&gt; messages from the wire protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;GetNodeData&lt;&#x2F;code&gt; and &lt;code&gt;NodeData&lt;&#x2F;code&gt; were introduced in protocol version &lt;code&gt;eth&#x2F;63&lt;&#x2F;code&gt; to allow for a sync mode called &quot;fast sync&quot;, which downloads the Ethereum state without executing all blocks. The sync algorithm works by requesting all state trie nodes and contract codes by their hash.&lt;&#x2F;p&gt;
&lt;p&gt;Serving &lt;code&gt;GetNodeData&lt;&#x2F;code&gt; requests requires clients to store state as a mapping of hashes to trie nodes. Avoiding the need to store such a mapping in the database is the main motivation for removing this request type.&lt;&#x2F;p&gt;
&lt;p&gt;At this time, some client implementations cannot serve &lt;code&gt;GetNodeData&lt;&#x2F;code&gt; requests because they do not store the state in a compatible way. The Ethereum Wire Protocol should accurately reflect the capabilities of clients, and should not contain messages which are impossible to implement in some clients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Remove the following message types from the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GetNodeData (0x0d)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;(eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NodeData (0x0e)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;(eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [value_0: B, value_1: B, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;A replacement for &lt;code&gt;GetNodeData&lt;&#x2F;code&gt; is available in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;snap.md&quot;&gt;snap protocol&lt;&#x2F;a&gt;. Specifically, clients can use the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;snap.md#getbytecodes-0x04&quot;&gt;GetByteCodes&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;snap.md#gettrienodes-0x06&quot;&gt;GetTrieNodes&lt;&#x2F;a&gt; messages instead of &lt;code&gt;GetNodeData&lt;&#x2F;code&gt;. The snap protocol can be used to implement the &quot;fast sync&quot; algorithm, though it is recommended to use it for &quot;snap sync&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP changes the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol and requires rolling out a new version, &lt;code&gt;eth&#x2F;67&lt;&#x2F;code&gt;. Supporting multiple versions of a wire protocol is possible. Rolling out a new version does not break older clients immediately, since they can keep using protocol version &lt;code&gt;eth&#x2F;66&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change consensus rules of the EVM and does not require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Royalty Bearing NFTs</title>
        <published>2022-03-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Andreas Freund</name><uri>https://github.com/Therecanbeonlyone1969</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4910/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/royalty-bearing-nfts/8453" />
        

        <id>https://wg-eips.ritovision.com/4910/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4910"
            label="ERC-4910" />
        

        
        

        
        <summary type="html">Extension of ERC-721 to correctly define, process, and pay (hierarchical) onchain NFT royalties.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4910/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The proposal directly connects NFTs and royalties in a smart contract architecture extending the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; standard, with the aim of precluding central authorities from manipulating or circumventing payments to those who are legally entitled to them.&lt;&#x2F;p&gt;
&lt;p&gt;The proposal builds upon the OpenZeppelin Smart Contract Toolbox architecture, and extends it to include royalty account management (CRUD), royalty balance and payments management, simple trading capabilities -- Listing&#x2F;De-Listing&#x2F;Buying -- and capabilities to trace trading on exchanges. The royalty management capabilities allow for hierarchical royalty structures, referred to herein as royalty trees, to be established by logically connecting a &quot;parent&quot; NFT to its &quot;children&quot;, and recursively enabling NFT &quot;children&quot; to have more children.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The management of royalties is an age-old problem characterized by complex contracts, opaque management, plenty of cheating and fraud.&lt;&#x2F;p&gt;
&lt;p&gt;The above is especially true for a hierarchy of royalties, where one or more assets is derived from an original asset such as a print from an original painting, or a song is used in the creation of another song, or distribution rights and compensation are managed through a series of affiliates.&lt;&#x2F;p&gt;
&lt;p&gt;In the example below, the artist who created the original is eligible to receive proceeds from every sale, and resale, of a print.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;.&#x2F;assets&#x2F;eip-4910-print-families.png&quot; alt=&quot;Fig1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The basic concept for hierarchical royalties utilizing the above &quot;ancestry concept&quot; is demonstrated in the figure below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;.&#x2F;assets&#x2F;eip-4910-royalties.png&quot; alt=&quot;Fig2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In order to solve for the complicated inheritance problem, this proposal breaks down the recursive problem of the hierarchy tree of depth N into N separate problems, one for each layer. This allows us to traverse the tree from its lowest level upwards to its root most efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;This affords creators, and the distributors of art derived from the original, the opportunity to achieve passive income from the creative process, enhancing the value of an NFT, since it now not only has intrinsic value but also comes with an attached cash flow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;outline&quot;&gt;Outline&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal introduces several new concepts as extensions to the ERC-721 standard that warrant explanation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Royalty Account (RA)&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;A Royalty Account is attached to each NFT through its &lt;code&gt;tokenId&lt;&#x2F;code&gt; and consists of several sub-accounts which can be accounts of individuals or other RAs. A Royalty Account is identified by an account identifier.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Account Type&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;This specifies if an RA Sub Account belongs to an individual (user) or is another RA. If there is another RA as an RA Sub Account, the allocated balance needs to be reallocated to the Sub Accounts making up the referenced RA.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Royalty Split&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;The percentage each Sub Account receives based on a sale of an NFT that is associated with an RA&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Royalty Balance&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;The royalty balance associated with an RA&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Sub Account Royalty Balance&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;The royalty balance associated to each RA Sub Account. Note that only individual accounts can carry a balance that can be paid out. That means that if an RA Sub Account is an RA, its final Sub Account balance must be zero, since all RA balances must be allocated to individual accounts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Token Type&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Token Type is given as either ETH or the symbol of the supported utility tokens such as &lt;code&gt;DAI&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Asset ID&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;This is the &lt;code&gt;tokenId&lt;&#x2F;code&gt; the RA belongs to.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Parent&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;This indicates which &lt;code&gt;tokenId&lt;&#x2F;code&gt; is the immediate parent of the &lt;code&gt;tokenId&lt;&#x2F;code&gt; to which an RA belongs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Below a non-normative overview is given of the data structures and functionality that are covered by the requirements in this document.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;data-structures&quot;&gt;Data Structures&lt;&#x2F;h4&gt;
&lt;p&gt;In order to create an interconnected data structure linking NFTs to RAs certain global data structures are required:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A Royalty Account and associated Royalty Sub Accounts to establish the concept of a Royalty Account with sub accounts.&lt;&#x2F;li&gt;
&lt;li&gt;Connecting a &lt;code&gt;tokenId&lt;&#x2F;code&gt; to a Royalty Account identifier.&lt;&#x2F;li&gt;
&lt;li&gt;A structure mapping parent-to-child NFT relationships.&lt;&#x2F;li&gt;
&lt;li&gt;A listing of token types and last validated balance (for trading and royalty payment purposes)&lt;&#x2F;li&gt;
&lt;li&gt;A listing of registered payments to be made in the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function and validated in &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;. This is sufficient, because a payment once received and distributed in the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function will be removed from the listing.&lt;&#x2F;li&gt;
&lt;li&gt;A listing of NFTs to be sold&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;royalty-account-functions&quot;&gt;Royalty Account Functions&lt;&#x2F;h4&gt;
&lt;p&gt;Definitions and interfaces for the Royalty Account RUD (Read-Update-Delete) functions. Because the RA is created in the minting function, there is no need to have a function to create a royalty account separately.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;minting-of-a-royalty-bearing-nft&quot;&gt;Minting of a Royalty Bearing NFT&lt;&#x2F;h4&gt;
&lt;p&gt;When an NFT is minted, an RA must be created and associated with the NFT and the NFT owner, and, if there is an ancestor, with the ancestor&#x27;s RA. To this end the specification utilizes the &lt;code&gt;_safemint&lt;&#x2F;code&gt; function in a newly defined &lt;code&gt;mint&lt;&#x2F;code&gt; function and applies various business rules on the input variables.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;listing-nfts-for-sale-and-removing-a-listing&quot;&gt;Listing NFTs for Sale and removing a Listing&lt;&#x2F;h4&gt;
&lt;p&gt;Authorized user addresses can list NFTs for sale for non-exchange mediated NFT purchases.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;payment-function-from-buyer-to-seller&quot;&gt;Payment Function from Buyer to Seller&lt;&#x2F;h4&gt;
&lt;p&gt;To avoid royalty circumvention, a buyer will always pay the NFT contract directly and not the seller. The seller is paid through the royalty distribution and can later request a payout.&lt;&#x2F;p&gt;
&lt;p&gt;The payment process depends on whether the payment is received in ETH or an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ERC-20 Token
&lt;ol&gt;
&lt;li&gt;The Buyer must &lt;code&gt;approve&lt;&#x2F;code&gt; the NFT contract for the purchase price, &lt;code&gt;payment&lt;&#x2F;code&gt; for the selected payment token (ERC-20 contract address).&lt;&#x2F;li&gt;
&lt;li&gt;For an ERC-20 payment token, the Buyer must then call the &lt;code&gt;executePayment&lt;&#x2F;code&gt; in the NFT contract -- the ERC-20 is not directly involved.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;For a non-ERC-20 payment, the Buyer must send a protocol token (ETH) to the NFT contract, and is required to send &lt;code&gt;msg.data&lt;&#x2F;code&gt; encoded as an array of purchased NFTs &lt;code&gt;uint256[] tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;modified-nft-transfer-function-including-required-trade-data-to-allocate-royalties&quot;&gt;Modified NFT Transfer Function including required Trade data to allocate Royalties&lt;&#x2F;h4&gt;
&lt;p&gt;The input parameters must satisfy several requirements for the NFT to be transferred AFTER the royalties have been properly distributed. Furthermore, the ability to transfer more than one token at a time is also considered.&lt;&#x2F;p&gt;
&lt;p&gt;The proposal defines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Input parameter validation&lt;&#x2F;li&gt;
&lt;li&gt;Payment Parameter Validation&lt;&#x2F;li&gt;
&lt;li&gt;Distributing Royalties&lt;&#x2F;li&gt;
&lt;li&gt;Update Royalty Account ownership with payout&lt;&#x2F;li&gt;
&lt;li&gt;Transferring Ownership of the NFT&lt;&#x2F;li&gt;
&lt;li&gt;Removing the Payment entry in &lt;code&gt;registeredPayment&lt;&#x2F;code&gt; after successful transfer&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Lastly, the approach to distributing royalties is to break down the hierarchical structure of interconnected Royalty Accounts into layers and then process one layer at time, where each relationship between a token and its ancestor is utilized to traverse the Royalty Account chain until the root ancestor and associated RA is reached.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;paying-out-royalties-to-the-nft-owner-from-address-in-safetransferfrom-function&quot;&gt;Paying out Royalties to the NFT Owner -- &lt;code&gt;from&lt;&#x2F;code&gt; address in &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; Function&lt;&#x2F;h4&gt;
&lt;p&gt;This is the final part of the proposal.&lt;&#x2F;p&gt;
&lt;p&gt;There are two versions of the payout function -- a &lt;code&gt;public&lt;&#x2F;code&gt; function and an &lt;code&gt;internal&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The public function has the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function royaltyPayOut (uint256 tokenId, address RAsubaccount, address payable payoutAccount, uint256 amount) public virtual nonReentrant returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where we only need the &lt;code&gt;tokenId&lt;&#x2F;code&gt;, the RA Sub Account address, &lt;code&gt;_RAsubaccount&lt;&#x2F;code&gt; which is the &lt;code&gt;owner&lt;&#x2F;code&gt;, and the amount to be paid out, &lt;code&gt;_amount&lt;&#x2F;code&gt;. Note that the function has &lt;code&gt;nonReentrant&lt;&#x2F;code&gt; modifier protection, because funds are being payed out.&lt;&#x2F;p&gt;
&lt;p&gt;To finally send a Payout payment, the following steps need to be taken:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;find the RA Sub Account based on &lt;code&gt;RAaccount&lt;&#x2F;code&gt; and the &lt;code&gt;subaccountPos&lt;&#x2F;code&gt; and extract the balance&lt;&#x2F;li&gt;
&lt;li&gt;extract &lt;code&gt;tokenType&lt;&#x2F;code&gt; from the Sub Account&lt;&#x2F;li&gt;
&lt;li&gt;based on the token type, send the payout payment (not exceeding the available balance)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;data-structures-1&quot;&gt;Data Structures&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;royalty-account-and-royalty-sub-accounts&quot;&gt;Royalty Account and Royalty Sub Accounts&lt;&#x2F;h4&gt;
&lt;p&gt;In order to create an interconnected data structure linking NFTs to RAs that is search optimized requires to make the following additions to the global data structures of an ERC-721.&lt;&#x2F;p&gt;
&lt;p&gt;Note, a Royalty Account is defined as a collection of Royalty Sub Accounts linked to a meta account. This meta account is comprised of general account identifiers particular to the NFT it is linked to such as asset identifier, parent identifier etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r1&quot;&gt;&lt;strong&gt;[R1]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;One or more Royalty Sub-Account MUST be linked to a Royalty Account.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r2&quot;&gt;&lt;strong&gt;[R2]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The account identifier of a Royalty Account, &lt;code&gt;raAccountId&lt;&#x2F;code&gt;, MUST be unique.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r3&quot;&gt;&lt;strong&gt;[R3]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;tokenId&lt;&#x2F;code&gt; of a NFT MUST be linked to a &lt;code&gt;raAccountID&lt;&#x2F;code&gt; in order to connect an &lt;code&gt;raAccountId&lt;&#x2F;code&gt; to a &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;print-child-nfts&quot;&gt;Print (Child) NFTs&lt;&#x2F;h4&gt;
&lt;p&gt;The set of requirement to manage Parent-Child NFT Relationships and constraints at each level of the NFT (family) tree e.g. number of children permitted, NFT parents have to be linked to their immediate NFT children are as follows.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r4&quot;&gt;&lt;strong&gt;[R4]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;There MUST be a link for direct parent-child relationships&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;nft-payment-tokens&quot;&gt;NFT Payment Tokens&lt;&#x2F;h4&gt;
&lt;p&gt;In order to capture royalties, an NFT contract must be involved in NFT trading. Therefore, the NFT contract needs to be aware of NFT payments, which in turn requires the NFT contract to be aware which tokens can be used for trading.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r5&quot;&gt;&lt;strong&gt;[R5]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;There MUST be a listing of supported token types&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since the NFT contract is managing royalty distributions and payouts as well as sales, it needs to track the last available balances of the allowed token types owned by the contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r6&quot;&gt;&lt;strong&gt;[R6]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;There MUST be a link of the last validated balance of an allowed token type in the contract to the respective allowed token contract.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;nft-listings-and-payments&quot;&gt;NFT Listings and Payments&lt;&#x2F;h4&gt;
&lt;p&gt;Since the contract is directly involved in the sales process, a capability to list one or more NFTs for sale is required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r7&quot;&gt;&lt;strong&gt;[R7]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;There MUST be a list of NFTs for sale.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r8&quot;&gt;&lt;strong&gt;[R8]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;A sales listing MUST have a unique identifier.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Besides listings, the contract is required to manage sales as well. This requires the capability to register a payment, either for immediate execution or for later payment such as in an auction situation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r9&quot;&gt;&lt;strong&gt;[R9]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;There MUST be a listing for registered payments&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r10&quot;&gt;&lt;strong&gt;[R10]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;A registered payment MUST have a unique identifier.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-constructor-and-global-variables-and-their-update-functions&quot;&gt;Contract Constructor and Global Variables and their update functions&lt;&#x2F;h4&gt;
&lt;p&gt;This standard extends the current ERC-721 constructor, and adds several global variables to recognize the special role of the creator of an NFT, and the fact that the contract is now directly involved in managing sales and royalties.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r11&quot;&gt;&lt;strong&gt;[R11]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The minimal contract constructor MUST contain the following input elements.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Definition of the contract constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param name as in ERC-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param symbol as in ERC-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param baseTokenURI as in ERC-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param allowedTokenTypes is the array of allowed tokens for payment&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;constructor(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string memory name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string memory symbol,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string memory baseTokenURI,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address[] memory allowedTokenTypes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) ERC721(name, symbol) {...}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;royalty-account-management&quot;&gt;Royalty Account Management&lt;&#x2F;h3&gt;
&lt;p&gt;Below are the definitions and interfaces for the Royalty Account RUD (Read-Update-Delete) functions. Since a Royalty Account is created in the NFT minting function, there is no need to have a separate function to create a royalty account.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;get-a-royalty-account&quot;&gt;Get a Royalty Account&lt;&#x2F;h4&gt;
&lt;p&gt;There is only one get function required because a Royalty Account and its sub accounts can be retrieved through the &lt;code&gt;tokenId&lt;&#x2F;code&gt; in the &lt;code&gt;ancestry&lt;&#x2F;code&gt; field of the Royalty Account.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r12&quot;&gt;&lt;strong&gt;[R12]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;getRoyaltyAccount&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to fetch a Royalty Account for a given tokenId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenId is the identifier of the NFT to which a Royalty Account is attached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param RoyaltyAccount is a data structure containing the royalty account information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param RASubAccount[] is an array of data structures containing the information of the royalty sub accounts associated with the royalty account&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;function getRoyaltyAccount (uint256 tokenId) public view virtual returns (address,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            RoyaltyAccount memory,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            RASubAccount[] memory);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a name=&quot;r13&quot;&gt;&lt;strong&gt;[R13]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The following business rules MUST be enforced in the &lt;code&gt;getRoyaltyAccount&lt;&#x2F;code&gt; function:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt; exists and is not burned&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;update-a-royalty-account&quot;&gt;Update a Royalty Account&lt;&#x2F;h4&gt;
&lt;p&gt;In order to update a Royalty Account, the caller must have both the &#x27;tokenId&#x27; and the &lt;code&gt;RoyaltyAccount&lt;&#x2F;code&gt; itself which can be obtained from the Royalty Account getter function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r14&quot;&gt;&lt;strong&gt;[R14]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;updateRoyaltyAccount&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to update a Royalty Account and its Sub Accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenId is the identifier of the NFT to which the Royalty Account to be updated is attached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param RoyaltyAccount is the Royalty Account and associated Royalty Sub Accounts with updated values  &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;function updateRoyaltyAccount (uint256 _tokenId, `RoyaltyAccount memory _raAccount) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The update functionality of a Royalty Account, while straightforward, is also highly nuanced. To avoid complicated change control rules such as multi-signature rules, Royalty Account changes are kept simple.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r15&quot;&gt;&lt;strong&gt;[R15]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules for the update function are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;An NFTs asset identifier MUST NOT be changed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;An NFTs ancestor MUST NOT be updated.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;An NFTs token type accepted for payment MUST NOT be updated.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The royalty balance in a Royalty Sub Account MUST NOT be changed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The royalty split inherited by the children from the NFT parent MUST NOT be changed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;New royalty split values MUST be larger than, or less than, or equal to any established boundary value for royalty splits, if it exists.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The number of existing Royalty Sub Account plus the number of new Royalty Sub Accounts to be added MUST be smaller or equal to an established boundary value, if it exists.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;The sum of all royalty splits across all existing and new Royalty Sub Accounts MUST equal to 1 or its equivalent numerical value at all times.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&#x27;msg.sender` MUST be equal to an account identifier in the Royalty Sub Account of the Royalty Account to be modified and that royalty sub account must be identified as not belonging to the parent NFT&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;9.1 &lt;em&gt;the Sub Account belonging to the account identifier MUST NOT be removed&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;9.2 &lt;em&gt;A royalty split MUST only be decreased, and either the existing sub account&#x27;s  royalty split MUST be increased accordingly such that the sum of all royalty splits remains equal to 1 or its numerical equivalent, or one or more new Royalty Sub Accounts MUST be added according to rule 10.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;9.3 &lt;em&gt;a royalty balance MUST NOT be changed&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;9.4 &lt;em&gt;an account identifier MUST NOT be NULL&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;If &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is equal to the account identifier of one of the Sub Account owners which is not the parent NFT, an additional Royalty Sub Accounts MAY be added&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;10.1 &lt;em&gt;if the royalty split of the Royalty Sub Account belonging to &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is reduced&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;then the royalty balance in each new Royalty Sub Account MUST be zero&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;and the sum of the new royalty splits data MUST be equal to the royalty split of the Royalty Sub Account of &lt;code&gt;msg.sender&lt;&#x2F;code&gt; before it was modified&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;10.2 &lt;em&gt;new account identifier MUST not be NULL&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;If the Royalty Account update is correct, the function returns &lt;code&gt;true&lt;&#x2F;code&gt;, otherwise &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;deleting-a-royalty-account&quot;&gt;Deleting a Royalty Account&lt;&#x2F;h4&gt;
&lt;p&gt;While sometimes deleting a Royalty Account is necessary, even convenient, it is a very costly function in terms of gas, and should not be used unless one is absolutely sure that the conditions enumerated below are met.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r16&quot;&gt;&lt;strong&gt;[R16]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;deleteRoyaltyAccount&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to delete a Royalty Account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenId is the identifier of the NFT to which the Royalty Account to be updated is attached&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;function deleteRoyaltyAccount (uint256 _tokenId) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a name=&quot;r17&quot;&gt;&lt;strong&gt;[R17]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules for this function are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;_tokenId&lt;&#x2F;code&gt; MUST be burned, i.e., have owner &lt;code&gt;address(0)&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;all &lt;code&gt;tokenId&lt;&#x2F;code&gt; numbers genealogically related to &lt;code&gt;_tokenId&lt;&#x2F;code&gt; either as ancestors or offspring MUST also be burnt.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;all balances in the Royalty Sub Accounts MUST be zero.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;nft-minting&quot;&gt;NFT Minting&lt;&#x2F;h3&gt;
&lt;p&gt;In extension to the ERC-721 minting capability, a Royalty Account with Royalty Sub Accounts are required to be added during the minting, besides establishing the NFT token specific data structures supporting constraints such as the maximum number of children an NFT can have.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r18&quot;&gt;&lt;strong&gt;[R18]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;When a new NFT is minted a Royalty Account with one or more Royalty Sub Accounts MUST be created and associated with the NFT and the NFT owner, and, if there is an ancestor, with the ancestor&#x27;s Royalty Account.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To this end the specification utilizes the ERC-721 &lt;code&gt;_safemint&lt;&#x2F;code&gt; function in a newly defined &lt;code&gt;mint&lt;&#x2F;code&gt; function, and applies various business rules on the function&#x27;s input variables.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;d1&quot;&gt;&lt;strong&gt;[D1]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;Note, that the &lt;code&gt;mint&lt;&#x2F;code&gt; function SHOULD have the ability to mint more than one NFT at a time.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r19&quot;&gt;&lt;strong&gt;[R19]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;Also, note that the &lt;code&gt;owner&lt;&#x2F;code&gt; of a new NFT MUST be the NFT contract itself.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r20&quot;&gt;&lt;strong&gt;[R20]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The non-contract owner of the NFT MUST be set as &lt;code&gt;isApproved&lt;&#x2F;code&gt; which allows the non-contract owner to operate just like the &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This strange choice in the two requirements above is necessary, because the NFT contract functions as an escrow for payments and royalties, and, hence, needs to be able to track payments received from buyers and royalties due to recipients, and to associate them with a valid &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r21&quot;&gt;&lt;strong&gt;[R21]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For compactness of the input, and since the token meta data might vary from token to token the MUST be a minimal data structure containing:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param parent is the parent tokenId of the (child) token, and if set to 0 then there is no parent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param canBeParent indicates if a tokenId can have children or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param maxChildren defines how many children an NFT can have.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param royaltySplitForItsChildren is the royalty percentage split that a child has to pay to its parent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param uri is the unique token URI of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a name=&quot;r22&quot;&gt;&lt;strong&gt;[R22]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;mint&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function creates one or more new NFTs with its relevant meta data necessary for royalties, and a Royalty Account with its associated met data for `to` address. The tokenId(s) will be automatically assigned (and available on the emitted {IERC-721-Transfer} event).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param to is the address to which the NFT(s) are minted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param nfttoken is an array of struct type NFTToken for the meta data of the minted NFT(s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenType is the type of allowed payment token for the NFT&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;function mint(address to, NFTToken[] memory nfttoken, address tokenType) public virtual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a name=&quot;r23&quot;&gt;&lt;strong&gt;[R23]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The following business rules for the &lt;code&gt;mint&lt;&#x2F;code&gt; function&#x27;s input data MUST be fulfilled:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The number of tokens to be minted MUST NOT be zero.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST have either the &lt;code&gt;MINTER_ROLE&lt;&#x2F;code&gt; or the &lt;code&gt;CREATOR_Role&lt;&#x2F;code&gt; identifying the creator of the first NFT.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;to&lt;&#x2F;code&gt; address MUST NOT be the zero address.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;to&lt;&#x2F;code&gt; address MUST NOT be a contract, unless it has been whitelisted -- see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#security-considerations&quot;&gt;Security Considerations&lt;&#x2F;a&gt; for more details.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenType&lt;&#x2F;code&gt; MUST be a token type supported by the contract.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;royaltySplitForItsChildren&lt;&#x2F;code&gt; MUST be less or equal to 100% or numerical equivalent thereof less any constraints such as platform fees&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;If the new NFT(s) cannot have children, &lt;code&gt;royaltySplitForItsChildren&lt;&#x2F;code&gt; MUST be zero.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;If the new NFT(s) has a parent, the parent NFT &lt;code&gt;tokenId&lt;&#x2F;code&gt; MUST exist.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The ancestry level of the parent MUST be less than the maximum number of allowed NFT generations, if specified.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The number of allowed children for an NFT to be minted MUST be less than the maximum number of allowed children, if specified.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;listing-and-de-listing-of-nfts-for-direct-sales&quot;&gt;Listing and De-Listing of NFTs for Direct Sales&lt;&#x2F;h3&gt;
&lt;p&gt;In the sales process, we need to minimally distinguish two types of transactions&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Exchange-mediated sales&lt;&#x2F;li&gt;
&lt;li&gt;Direct sales&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first type of transaction does not require that the smart contract is aware of a sales listing since the exchange contract will trigger payment and transfer transactions directly with the NFT contract as the owner. However, for the latter transaction type it is essential, since direct sales are required to be mediated at every step by the smart contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r24&quot;&gt;&lt;strong&gt;[R24]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For direct sales, NFT listing, und de-listing, transactions MUST be executed through the NFT smart contract.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Exchange-mediated sales will be discussed when this document discusses payments.&lt;&#x2F;p&gt;
&lt;p&gt;In direct sales, authorized user addresses can list NFTs for sale, see the business rules below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r25&quot;&gt;&lt;strong&gt;[R25]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;listNFT&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to list one or more NFTs for direct sales&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenIds is the array of tokenIds to be included in the listing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param price is the price set by the owner for the listed NFT(s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenType is the payment token type allowed for the listing&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;function listNFT (uint256[] calldata tokenIds, uint256 price, address tokenType) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r26&quot;&gt;&lt;strong&gt;[R26]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules of the &lt;code&gt;listNFT&lt;&#x2F;code&gt; function are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;there MUST NOT already be a listing for one or more NFTs in the &lt;code&gt;listedNFT&lt;&#x2F;code&gt; mapping of the proposed listing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;seller&lt;&#x2F;code&gt; MUST be equal to &lt;code&gt;getApproved(tokenId[i])&lt;&#x2F;code&gt; for all NFTs in the proposed listing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokenType&lt;&#x2F;code&gt; MUST be supported by the smart contract.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;price&lt;&#x2F;code&gt; MUST be larger than &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r27&quot;&gt;&lt;strong&gt;[R27]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;If the conditions in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r26&quot;&gt;&lt;strong&gt;[R26]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; are met, then the NFT sales list MUST be updated.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Authorized user addresses can also remove a direct sale listing of NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r28&quot;&gt;&lt;strong&gt;[R28]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;removeNFTListing&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to de-list one or more NFTs for direct sales&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param listingId is the identifier of the NFT listing&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;function removeNFTListing (uint256 listingId) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r29&quot;&gt;&lt;strong&gt;[R29]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules of the &lt;code&gt;removeNFTListing&lt;&#x2F;code&gt; function below MUST be adhered to:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;the registered payment entry MUST be NULL&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender = getApproved(tokenId)&lt;&#x2F;code&gt; for the NFT listing&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r30&quot;&gt;&lt;strong&gt;[R30]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;If the conditions in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r29&quot;&gt;&lt;strong&gt;[R29]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; are met, then the NFT sales listing MUST be removed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;payments-for-nft-sales&quot;&gt;Payments for NFT Sales&lt;&#x2F;h3&gt;
&lt;p&gt;As noted before, a buyer will always pay the NFT contract directly and not the seller. The seller is paid through the royalty distribution and can later request a payout to their wallet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r31&quot;&gt;&lt;strong&gt;[R31]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The payment process requires either one or two steps:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;For an ERC-20 token&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The buyer MUST &lt;code&gt;approve&lt;&#x2F;code&gt; the NFT contract for the purchase price, &lt;code&gt;payment&lt;&#x2F;code&gt;, for the selected payment token type.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The buyer MUST call the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;For a protocol token&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The buyer MUST call a payment fallback function with &lt;code&gt;msg.data&lt;&#x2F;code&gt; not NULL.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a name=&quot;r32&quot;&gt;&lt;strong&gt;[R32]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For an ERC-20 token type, the required &lt;code&gt;executePayment&lt;&#x2F;code&gt; function interface MUST adhere to the definition below&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to make a NFT direct sales or exchange-mediate sales payment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param receiver is the address of the receiver of the payment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param seller is the address of the NFT seller &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenIds are the tokenIds of the NFT to be bought&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param payment is the amount of that payment to be made&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenType is the type of payment token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param trxnType is the type of payment transaction -- minimally direct sales or exchange-mediated&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;function executePayment (address receiver, address seller, uint 256[] tokenIds, uint256 payment, string tokenType, int256 trxnType) public virtual nonReentrant returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r33&quot;&gt;&lt;strong&gt;[R33]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;Independent of &lt;code&gt;trxnType&lt;&#x2F;code&gt;, the business rules for the input data are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;All purchased NFTs in the &lt;code&gt;tokenIds&lt;&#x2F;code&gt; array MUST exist and MUST NOT be burned.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenType&lt;&#x2F;code&gt; MUST be a supported token.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;trxnType&lt;&#x2F;code&gt; MUST be set to either &lt;code&gt;0&lt;&#x2F;code&gt; (direct sale) or &lt;code&gt;1&lt;&#x2F;code&gt; (exchange-mediate sale), or another supported type.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;receiver&lt;&#x2F;code&gt; MAY be NULL but MUST NOT be the Zero Address.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;seller&lt;&#x2F;code&gt; MUST be the address in the corresponding listing.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST not be a contract, unless it is whitelisted in the NFT contract.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the following, this document will only discuss the differences between the two minimally required transaction types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r34&quot;&gt;&lt;strong&gt;[R34]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For &lt;code&gt;trxnType = 0&lt;&#x2F;code&gt;, the payment data MUST to be validated against the listing, based on the following rules:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;NFT(s) MUST be listed&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;payment&lt;&#x2F;code&gt; MUST be larger or equal to the listing price.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The listed NFT(s) MUST match the NFT(s) in the payment data.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The listed NFT(s) MUST be controlled by &lt;code&gt;seller&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r35&quot;&gt;&lt;strong&gt;[R35]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;If all checks in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r33&quot;&gt;&lt;strong&gt;[R33]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;, and in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r34&quot;&gt;&lt;strong&gt;[R34]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; for &lt;code&gt;trxnType = 0&lt;&#x2F;code&gt;, are passed, the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function MUST call the &lt;code&gt;transfer&lt;&#x2F;code&gt; function in the ERC-20 contract identified by &lt;code&gt;tokenType&lt;&#x2F;code&gt; with &lt;code&gt;recipient = address(this)&lt;&#x2F;code&gt; and &lt;code&gt;amount = payment&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note the NFT contract pays itself from the available allowance set in the &lt;code&gt;approve&lt;&#x2F;code&gt; transaction from the buyer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r36&quot;&gt;&lt;strong&gt;[R36]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For &lt;code&gt;trxnType = 1&lt;&#x2F;code&gt;, and for a successful payment, the &lt;code&gt;registeredPayment&lt;&#x2F;code&gt; mapping MUST updated with the payment, such that it can be validated when the NFT is transferred in a separate &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; call, and &lt;code&gt;true&lt;&#x2F;code&gt; MUST be returned as the return value of the function, if successful, &lt;code&gt;false&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r37&quot;&gt;&lt;strong&gt;[R37]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For &lt;code&gt;trxnType = 0&lt;&#x2F;code&gt;, an &lt;code&gt;internal&lt;&#x2F;code&gt; version of the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function with message data MUST be called to transfer the NFTs to the buyer, and upon success, the buyer MUST be given the &lt;code&gt;MINTER_ROLE&lt;&#x2F;code&gt;, unless the buyer already has that role.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note, the &lt;code&gt;_safeTransferFrom&lt;&#x2F;code&gt; function has the same structure as &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; but skips the input data validation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r38&quot;&gt;&lt;strong&gt;[R38]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For &lt;code&gt;trxnType = 0&lt;&#x2F;code&gt;, and if the NFT transfer is successful, the listing of the NFT MUST be removed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r39&quot;&gt;&lt;strong&gt;[R39]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For a protocol token as a payment token, and independent of &lt;code&gt;trxnType&lt;&#x2F;code&gt;, the buyer MUST send protocol tokens to the NFT contract as the escrow, and &lt;code&gt;msg.data&lt;&#x2F;code&gt; MUST encode the array of paid for NFTs &lt;code&gt;uint256[] tokenIds&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r40&quot;&gt;&lt;strong&gt;[R40]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For the NFT contract to receive a protocol token, a payable fallback function (&lt;code&gt;fallback() external payable&lt;&#x2F;code&gt;) MUST be implemented.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that since the information for which NFTs the payment was for must be passed, a simple &lt;code&gt;receive()&lt;&#x2F;code&gt; fallback function cannot be allowed since it does not allow for &lt;code&gt;msg.data&lt;&#x2F;code&gt; to be sent with the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r41&quot;&gt;&lt;strong&gt;[R41]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;&lt;code&gt;msg.data&lt;&#x2F;code&gt; for the fallback function MUST minimally contain the following data:
&lt;code&gt;address memory seller, uint256[] memory _tokenId, address memory receiver, int256 memory trxnType&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r42&quot;&gt;&lt;strong&gt;[R42]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;If &lt;code&gt;trxnType&lt;&#x2F;code&gt; is not equal to either &#x27;0&#x27; or &#x27;1&#x27;, or another supported type, then the fallback function MUST &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r43&quot;&gt;&lt;strong&gt;[R43]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For &lt;code&gt;trxnType&lt;&#x2F;code&gt; equal to either &#x27;0&#x27; or &#x27;1&#x27;, the requirements &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r33&quot;&gt;&lt;strong&gt;[R33]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; through &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4910&#x2F;#r38&quot;&gt;&lt;strong&gt;[R38]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; MUST be satisfied for the fallback function to successfully execute, otherwise the fallback function MUST &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r44&quot;&gt;&lt;strong&gt;[R44]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;In case of a transaction failure (for direct sales, &lt;code&gt;trxnType = 0&lt;&#x2F;code&gt;), or the buyer of the NFT listing changing their mind (for exchange-mediated sales, &lt;code&gt;trxnType = 1&lt;&#x2F;code&gt;), the submitted payment MUST be able to revert using the &lt;code&gt;reversePayment&lt;&#x2F;code&gt; function where the function interface is defined below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Definition of the function enabling the reversal of a payment before the sale is complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param paymentId is the unique identifier for which a payment was made&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenType is the type of payment token used in the payment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function reversePayment(uint256 paymentId, string memory tokenType) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;Note, &lt;code&gt;reentrancy&lt;&#x2F;code&gt; protection through e.g. &lt;code&gt;nonReentrant&lt;&#x2F;code&gt; from the Open Zeppelin library is strongly advised since funds are being paid out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r45&quot;&gt;&lt;strong&gt;[R45]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules for the &lt;code&gt;reversePayment&lt;&#x2F;code&gt; function are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;There MUST be registered payment for a given &lt;code&gt;paymentId&lt;&#x2F;code&gt; and &lt;code&gt;tokenType&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST be the buyer address in the registered payment.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The payment amount must be larger than &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The registered payment MUST be removed when the payment has been successfully reverted, otherwise the function must fail.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;modified-nft-transfer-function&quot;&gt;Modified NFT Transfer function&lt;&#x2F;h3&gt;
&lt;p&gt;This document adheres to the ERC-721 interface format for the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function as given below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) external virtual override&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note, that the input parameters must satisfy several requirements for the NFT(s) to be transferred AFTER royalties have been properly distributed. Note also, that the ability to transfer more than one token at a time is required. However, the standard interface only allows one token to be transferred at a time. In order to remain compliant with the ERC-721 standard, this document uses &lt;code&gt;tokenId&lt;&#x2F;code&gt; only for the first NFT to be transferred. All other transfer relevant data is encoded in &lt;code&gt;_data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The high-level requirements are as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The payment parameters of the trade encoded in &lt;code&gt;_data&lt;&#x2F;code&gt; must be validated.&lt;&#x2F;li&gt;
&lt;li&gt;The seller and the sold NFT token(s) must exist, and the seller must be the owner of the token.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; must be the seller address or an approved address.&lt;&#x2F;li&gt;
&lt;li&gt;the payment of the trade received by the NFT smart contract is correctly disbursed to all Royalty Sub Account owners.&lt;&#x2F;li&gt;
&lt;li&gt;the NFT token is transferred after all Royalty Sub Accounts and their holders associated with the NFT token(s) have been properly credited.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also, note that in order to avoid royalty circumvention attacks, there is only one NFT transfer function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r46&quot;&gt;&lt;strong&gt;[R46]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;Therefore, &lt;code&gt;transferFrom&lt;&#x2F;code&gt; and &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; without &lt;code&gt;data&lt;&#x2F;code&gt; MUST be disabled.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be achieved through for example a &lt;code&gt;revert&lt;&#x2F;code&gt; statement in an &lt;code&gt;override&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r47&quot;&gt;&lt;strong&gt;[R47]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The requirements on input parameters of the function are as follows&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST not be &lt;code&gt;address(0)&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST be the owner or &lt;code&gt;approved&lt;&#x2F;code&gt; for &lt;code&gt;tokenId&lt;&#x2F;code&gt; and the other tokens included in &lt;code&gt;_data&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST not be a smart contract unless whitelisted.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;a Royalty Account MUST be associated to &lt;code&gt;tokenId&lt;&#x2F;code&gt; and the other tokens included in &lt;code&gt;_data&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;_data&lt;&#x2F;code&gt; MUST NOT be NULL.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; MUST be equal to &lt;code&gt;from&lt;&#x2F;code&gt; or an &lt;code&gt;approved&lt;&#x2F;code&gt; address, or a whitelisted contract.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note, that in the context of this document only the scenario where the calling contract is still being created, i.e., the constructor being executed is a possible attack vector, and should to be carefully treated in the transfer scenario.&lt;&#x2F;p&gt;
&lt;p&gt;Turning to the &lt;code&gt;_data&lt;&#x2F;code&gt; object.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r48&quot;&gt;&lt;strong&gt;[R48]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; object MUST minimally contain the following payment parameters:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Seller Address as &lt;code&gt;address&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Buyer Address as &lt;code&gt;address&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Receiver Address as `address.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Token identifiers as &lt;code&gt;uint256[]&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Token type used for payment.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Payment amount paid to NFT contract as &lt;code&gt;uint256&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;a registered payment identifier.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;blockchain ID, &lt;code&gt;block.chainid&lt;&#x2F;code&gt;, of the underlying blockchain.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r49&quot;&gt;&lt;strong&gt;[R49]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The following business rules MUST be met for the payment data in &#x27;_data&#x27;:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;seller == from&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenId[0] == tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Each token in &lt;code&gt;_tokenId&lt;&#x2F;code&gt; has an associated Royalty Account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;chainid == block.chainid&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;buyer&lt;&#x2F;code&gt; is equal to the buyer address in the registered payment for the given ``paymentId.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;receiver == to&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;the receiver of the token is not the seller.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;the receiver of the token is not a contract or is a whitelisted contract&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;For all NFTs in the payment, &lt;code&gt;tokenId[i] = registeredPayment[paymentId].boughtTokens[i]&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenType&lt;&#x2F;code&gt; is supported in the contract.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;allowedToken[tokenType]&lt;&#x2F;code&gt; is not NULL.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenType = registeredPayment[paymentId].tokenType&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;payment &amp;gt; lastBalanceAllowedToken[allowedToken[listingId]]&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;payment = registeredPayment[paymentId].payment&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;distributing-royalties-in-the-transfer-function&quot;&gt;Distributing Royalties in the Transfer Function&lt;&#x2F;h3&gt;
&lt;p&gt;The approach to distributing royalties is to break down the hierarchical structure of interconnected Royalty Accounts into layers, and then process one layer at time, where each relationship between a NFT and its ancestor is utilized to traverse the Royalty Account chain until the root ancestor and its associated Royalty Account.&lt;&#x2F;p&gt;
&lt;p&gt;Note, that the distribution function assumes that the payment made is for ALL tokens in the requested transfer. That means, that &lt;code&gt;payment&lt;&#x2F;code&gt; for the distribution function is equally divided between all NFTs included in the payment.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r5&quot;&gt;&lt;strong&gt;[R50]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; *The &lt;code&gt;distributePayment&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to distribute a payment as royalties to a chain of Royalty Accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenId is a tokenId included in the sale and used to look up the associated Royalty Account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param payment is the payment (portion) to be distributed as royalties&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;function distributePayment (uint256 tokenId, uint265 payment) internal virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned before, the internal &lt;code&gt;distributePayment&lt;&#x2F;code&gt; function is called within the modified &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;Note, that it is necessary to multiply two &lt;code&gt;uint256&lt;&#x2F;code&gt; numbers with each other -- the payment amount with the royalty split percentage expressed as a whole number e.g. &lt;code&gt;10000 = 100%&lt;&#x2F;code&gt;. And then divide the result by the whole number representing &lt;code&gt;100%&lt;&#x2F;code&gt; in order to arrive at the correct application of the royalty split percentage to the payment amount. This requires careful treatment of numbers in the implementation to prevent issues such as buffer over or under runs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r51&quot;&gt;&lt;strong&gt;[R51]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The processing logic of &lt;code&gt;distributePayment&lt;&#x2F;code&gt; function MUST be as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Load the Royalty Account (&lt;code&gt;RA&lt;&#x2F;code&gt;) and associated Royalty Sub Accounts using the passed &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;For each Royalty Sub Account in &lt;code&gt;RA&lt;&#x2F;code&gt; apply the following rules:&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;If a Royalty Sub Account in &lt;code&gt;RA&lt;&#x2F;code&gt; has &lt;code&gt;isIndividual&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt; then&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;apply the royalty percentage of that Royalty Sub Account to &lt;code&gt;payment&lt;&#x2F;code&gt; and add the calculated amount, e.g. &lt;code&gt;royaltyAmountTemp&lt;&#x2F;code&gt;, to the &lt;code&gt;royaltybalance&lt;&#x2F;code&gt; of that Royalty Sub Account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;emit an event as a notification of payment to the &lt;code&gt;accountId&lt;&#x2F;code&gt; of the Royalty Sub Account containing: assetId, accountId, tokenType, royaltybalance.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;in the RA add &lt;code&gt;royaltyamountTemp&lt;&#x2F;code&gt; amount to &lt;code&gt;balance&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;If a Royalty Sub Account in &lt;code&gt;RA&lt;&#x2F;code&gt; has &lt;code&gt;isIndividual&lt;&#x2F;code&gt; set to &lt;code&gt;false&lt;&#x2F;code&gt; then&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;apply the royalty percentage of that Royalty Sub Account to &lt;code&gt;payment&lt;&#x2F;code&gt; and store temporarily in a new variable e.g. &lt;code&gt;RApaymenttemp&lt;&#x2F;code&gt;, but do not update the &lt;code&gt;royaltybalance&lt;&#x2F;code&gt; of the Royalty Sub Account which remains &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;then use &lt;code&gt;ancestor&lt;&#x2F;code&gt; to obtain the &lt;code&gt;RA&lt;&#x2F;code&gt; connected to &lt;code&gt;ancestor&lt;&#x2F;code&gt; e.g. via a look up through a Royalty Account mapping.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;load the new RA&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;if &lt;code&gt;isIndividual&lt;&#x2F;code&gt; of the Royalty Sub Account is set to &lt;code&gt;true&lt;&#x2F;code&gt;, pass through the Royalty Sub Accounts of the next &lt;code&gt;RA&lt;&#x2F;code&gt;, and apply the rule for &lt;code&gt;isIndividual = true&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;if &lt;code&gt;isIndividual&lt;&#x2F;code&gt; of the Royalty Sub Account is set to &lt;code&gt;false&lt;&#x2F;code&gt;, pass through the Royalty Sub Accounts of the next &lt;code&gt;RA&lt;&#x2F;code&gt;, and apply the rule for &lt;code&gt;isIndividual = false&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Repeat the procedures for &lt;code&gt;isIndividual&lt;&#x2F;code&gt; equal to &lt;code&gt;true&lt;&#x2F;code&gt; and &lt;code&gt;false&lt;&#x2F;code&gt; until a &lt;code&gt;RA&lt;&#x2F;code&gt; is reached that does not have an &lt;code&gt;ancestor&lt;&#x2F;code&gt;, and where all Royalty Sub Accounts have&lt;code&gt;isIndividual&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt;, and apply the rule for a Royalty Sub Account that has &lt;code&gt;isIndividual&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt; to all Royalty Sub Accounts in that &lt;code&gt;RA&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;update-royalty-sub-account-ownership-with-payout-to-approved-address-from&quot;&gt;Update Royalty Sub Account Ownership with Payout to approved Address (&lt;code&gt;from&lt;&#x2F;code&gt;)&lt;&#x2F;h3&gt;
&lt;p&gt;In order to simplify the ownership transfer, first the approved address -- the non-contract NFT owner --, &lt;code&gt;from&lt;&#x2F;code&gt;, is paid out its share of the royalties. And then the Royalty Sub Account is updated with the new owner, &lt;code&gt;to&lt;&#x2F;code&gt;. This step repeats for each token to be transferred.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r52&quot;&gt;&lt;strong&gt;[R52]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The business rules are as follows:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;the internal version of the&lt;code&gt;royaltyPayOut&lt;&#x2F;code&gt; function MUST pay out the entire royalty balance of the Royalty Sub Account owned by the &lt;code&gt;from&lt;&#x2F;code&gt; address to the &lt;code&gt;from&lt;&#x2F;code&gt; address.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;the Royalty Sub Account MUST only be updated with the new owner only once the payout function has successfully completed and the &lt;code&gt;royaltybalance = 0&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The last step in the process chain is transferring the NFTs in the purchase to the &lt;code&gt;to&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r53&quot;&gt;&lt;strong&gt;[R53]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;For every NFT (in the batch) the &#x27;to&#x27; address MUST be `approved&#x27; (ERC-721 function) to complete the ownership transfer:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_approve(to, tokenId[i]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The technical NFT owner remains the NFT contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removing-the-payment-entry-after-successful-transfer&quot;&gt;Removing the Payment Entry after successful Transfer&lt;&#x2F;h3&gt;
&lt;p&gt;Only after the real ownership of the NFT, the approved address, has been updated, the payment registry entry can be removed to allow the transferred NFTs to be sold again.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r54&quot;&gt;&lt;strong&gt;[R54]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;After the &lt;code&gt;approve&lt;&#x2F;code&gt; relationship has been successfully updated to the &lt;code&gt;to&lt;&#x2F;code&gt; address, the registered payment MUST be removed.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;paying-out-royalties-to-the-from-address-in-safetransferfrom-function&quot;&gt;Paying out Royalties to the &lt;code&gt;from&lt;&#x2F;code&gt; Address in &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; Function&lt;&#x2F;h3&gt;
&lt;p&gt;There are two versions of the payout function -- a &lt;code&gt;public&lt;&#x2F;code&gt; and an &lt;code&gt;internal&lt;&#x2F;code&gt; function -- depending on whether there is a payout during a purchase, or a payout is requested by a Royalty Sub Account owner.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r55&quot;&gt;&lt;strong&gt;[R55]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The public &lt;code&gt;royaltyPayOut&lt;&#x2F;code&gt; function interface MUST adhere to the definition below:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @dev Function to payout a royalty payment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param tokenId is the identifier of the NFT token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param RAsubaccount is the address of the Royalty Sub Account from which the payout should happen&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param receiver is the address to receive the payout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&#x2F; @param amount is the amount to be paid out&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;function royaltyPayOut (uint256 tokenId, address RAsubaccount, address payable payoutAccount, uint256 amount) public virtual nonReentrant returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Boolean return value is &lt;code&gt;true&lt;&#x2F;code&gt; for a successful function execution, and &lt;code&gt;false&lt;&#x2F;code&gt; for an unsuccessful function execution.&lt;&#x2F;p&gt;
&lt;p&gt;Note, that the function has &lt;code&gt;reentrancy&lt;&#x2F;code&gt; protection through &lt;code&gt;nonReentrant&lt;&#x2F;code&gt; from the Open Zeppelin library since funds are being paid out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a name=&quot;r56&quot;&gt;&lt;strong&gt;[R56]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The input parameters of the &lt;code&gt;royaltyPayOut&lt;&#x2F;code&gt; function MUST satisfy the following requirements:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;msg.sender == RAsubaccount&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt; must exist and must not be burned.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;tokenId&lt;&#x2F;code&gt; must be associated with a Royalty Account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;RAsubaccount&lt;&#x2F;code&gt; must be a valid &lt;code&gt;accountId&lt;&#x2F;code&gt; in a Royalty Sub Account of the Royalty Account of the `tokenId&#x27;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;isIndividual == true&lt;&#x2F;code&gt; for the Royalty Sub Account, &lt;code&gt;RAsubaccount&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;*&lt;code&gt;amount &amp;lt;= royaltybalance&lt;&#x2F;code&gt; of the Royalty Sub Account, &lt;code&gt;RAsubaccount.*&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r57&quot;&gt;&lt;strong&gt;[R57]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The internal &lt;code&gt;_royaltyPayOut&lt;&#x2F;code&gt; function interface MUST adhere to the definition below&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function _royaltyPayOut (uint256 tokenId, address RAsubaccount, address payable payoutAccount, uint256 amount) public virtual returns (bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a name=&quot;r58&quot;&gt;&lt;strong&gt;[R58]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; *The internal &lt;code&gt;_royaltyPayOut&lt;&#x2F;code&gt; function MUST perform the following actions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;send the payment to the &lt;code&gt;payoutaccount&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;update the &lt;code&gt;royaltybalance&lt;&#x2F;code&gt; of the &lt;code&gt;RAsubaccount&lt;&#x2F;code&gt; of the Royalty Account upon successful transfer.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a name=&quot;r59&quot;&gt;&lt;strong&gt;[R59]&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; &lt;em&gt;The following steps MUST be taken to send out a royalty payment to its recipient:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;find the Royalty Sub Account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;extract &lt;code&gt;tokenType&lt;&#x2F;code&gt; from the Royalty Sub Account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;based on the token type send to the &lt;code&gt;payoutAccount&lt;&#x2F;code&gt; either&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&#x27;ETH&#x27; &#x2F; relevant protocol token or&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;another token based on token type&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;and only if the payout transaction is successful, deduct &lt;code&gt;amount&lt;&#x2F;code&gt; from &lt;code&gt;royaltybalance&lt;&#x2F;code&gt; of the Royalty Sub Account,&lt;code&gt;RAsubaccount&lt;&#x2F;code&gt;, and then return &lt;code&gt;true&lt;&#x2F;code&gt; as the function return parameter, otherwise return &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Royalties for NFTs is at its core a distribution licensing problem. A buyer obtains the right to an asset&#x2F;content which might or might not be reproducible, alterable etc. by the buyer or agents of the buyer. Therefore, a comprehensive specification must address a hierarchy of royalties, where one or more assets are derived from an original asset as described in the Motivation section in detail. Consequently, a design must solve for a multi-level inheritance, and thus, recursion problem.&lt;&#x2F;p&gt;
&lt;p&gt;In order to solve for the complicated inheritance problem, this proposal design breaks down the recursive problem of the hierarchy first into a tree of depth N. And the further breaks down the tree structure into N separate problems, one for each layer. This design allows one to traverse the tree from its lowest level upwards to its root most efficiently. This is achieved with the design for the &lt;code&gt;distributePayment&lt;&#x2F;code&gt; function and the NFT data structures allowing for the tree structure e.g. &lt;code&gt;ancestry&lt;&#x2F;code&gt;,&lt;code&gt;royaltyAccount&lt;&#x2F;code&gt;, &lt;code&gt;RAsubaccount&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In order to avoid massive gas costs during the payout of royalties, possibly exceeding block gas limits for large royalty trees, the design needed to create a royalty accounting system to maintain royalty balances for recipients as done with the &lt;code&gt;royaltyAccount&lt;&#x2F;code&gt;, &#x27;RAsubaccount&#x27; data structures and the associated CRUD operations, as well as require that royalty payouts are done by individual and by request, only, as is achieved with the &lt;code&gt;royaltyPayout&lt;&#x2F;code&gt; function design.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, the design had to ensure that in order to account for and payout royalties the smart contract must be in the &quot;know&quot; of all buying and selling of an NFT including the exchange of monies. This buying and selling can be either direct through the NFT contract or can be exchange-mediated as is most often the case today -- which is a centralizing factor! The chosen design for purchasing is accounting for those two modes.&lt;&#x2F;p&gt;
&lt;p&gt;Keeping the NFT contract in the &quot;know&quot; at the beginning of the purchase process requires that authorized user addresses can list NFTs for sale for direct sales , whereas for exchange-mediated purchases, a payment must be registered with the NFT contract before the purchase can be completed.&lt;&#x2F;p&gt;
&lt;p&gt;The design needed to avoid royalty circumvention during the purchase process, therefore, the NFT must be kept in the &quot;know&quot;, a buyer will always have to pay the NFT contract directly and not the seller for both purchasing modes. The seller is subsequently paid through the royalty distribution function in the NFT contract. As a consequence, and a key design choice, and to stay compliant with ERC-721, the NFT contract must be the owner of the NFT, and the actual owner is an &lt;code&gt;approved&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;The specification design also needed to account for that the payment process depends on whether the payment is received in ETH or an ERC-20 token:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ERC-20 Token
&lt;ol&gt;
&lt;li&gt;The Buyer must &lt;code&gt;approve&lt;&#x2F;code&gt; the NFT contract for the purchase price, &lt;code&gt;payment&lt;&#x2F;code&gt; for the selected payment token (ERC-20 contract address).&lt;&#x2F;li&gt;
&lt;li&gt;For an ERC-20 payment token, the Buyer must then call the &lt;code&gt;executePayment&lt;&#x2F;code&gt; in the NFT contract -- the ERC-20 is not directly involved.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;For a non-ERC-20 payment, the Buyer must send a protocol token (ETH) to the NFT contract, and is required to send encoded listing and payment information.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In addition, the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function had to be designed to handle both direct sales (through the NFT contract) and exchange-mediated sales which required the introduction of an indicator whether the purchase is direct or exchange-mediated.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;executePayment&lt;&#x2F;code&gt; function also has to  handle the NFT transfer and purchase clean up -- removal  of a listing, or removal of a registered payment, distribution of royalties, payment to the seller, and finally transfer to the seller.&lt;&#x2F;p&gt;
&lt;p&gt;To stay compliant with the ERC-721 design but avoid royalty circumvention, all transfer functions must be disabled save the one that allows for additional information to be submitted with the function in order to manage the complicated purchase cleanup process -- &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;. To ensure safety, the design enforces that input parameters must satisfy several requirements for the NFT to be transferred AFTER the royalties have been properly distributed, not before. The design accounts for the fact that we need to treat transfer somewhat differently for direct sales versus exchange mediated sales.&lt;&#x2F;p&gt;
&lt;p&gt;Finally the specification needed to take into account that NFTs must be able to be &lt;code&gt;minted&lt;&#x2F;code&gt; and &lt;code&gt;burned&lt;&#x2F;code&gt; to maintain compliance with the ERC-721 specification while also having to set up all the data structures for the tree.&lt;&#x2F;p&gt;
&lt;p&gt;The design enforces that when an NFT is minted, a royalty account for that NFT must be created and associated with the NFT and the NFT owner, and, if there is an ancestor of the NFT with the ancestor&#x27;s royalty account to enforces the tree structure. To this end the specification utilizes the ERC-721 &lt;code&gt;_safemint&lt;&#x2F;code&gt; function in a newly defined &lt;code&gt;mint&lt;&#x2F;code&gt; function and applies various business rules on the input variables required to ensure proper set-up.&lt;&#x2F;p&gt;
&lt;p&gt;An NFT with a royalty account can be burned. However, several things have to be true to avoid locking funds not only for the royalty account of the NFT but also its descendants, if they exist. That means that all royalties for the NFT and its descendants, if they exists, must be paid out. Furthermore, if descendants exist, they must have been burned before an ancestor can be burned. If those rules are not enforced the cleanly, the hierarchical royalty structure in part of the tree can break down and lead to lost funds, not paid out royalties etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is backwards compatible to the ERC-721 standard introducing new interfaces and functionality but retaining the core interfaces and functionality of the ERC-721 standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;A full test suite is part of the reference implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The Treetrunk reference implementation of the standard can be found in the public treetrunkio Github repo under treetrunk-nft-reference-implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Given that this EIP introduces royalty collection, distribution, and payouts to the ERC-721 standard, the number of attack vectors increases. The most important attack vector categories and their mitigation are discussed below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Payments and Payouts&lt;&#x2F;strong&gt;:
&lt;ul&gt;
&lt;li&gt;Reentrancy attacks are mitigated through a reentrancy protection on all payment functions. See for example the Open Zeppelin reference implementation .&lt;&#x2F;li&gt;
&lt;li&gt;Payouts from unauthorized accounts. Mitigation: Royalty Sub Accounts require at least that &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the Royalty Sub Account owner.&lt;&#x2F;li&gt;
&lt;li&gt;Payments could get stuck in the NFT contract if the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function fails. Mitigation: For exchange-mediated sales, a buyer can always reverse a payment with &lt;code&gt;reversePayment&lt;&#x2F;code&gt; if the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function fails. For direct sales, &lt;code&gt;reversePayment&lt;&#x2F;code&gt; will be directly triggered in the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Circumventing Royalties&lt;&#x2F;strong&gt;:
&lt;ul&gt;
&lt;li&gt;Offchain Key exchanges
&lt;ul&gt;
&lt;li&gt;Exchanging a private key for money off chain can not be prevented in any scenario.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Smart Contract Wallets as NFT owners
&lt;ul&gt;
&lt;li&gt;A Smart Contract Wallet controlled by multiple addresses could own an NFT and the owners could transfer the asset within the wallet with an off chain money exchange. Mitigation: Prohibit that Smart Contracts can own an NFT unless explicitly allowed to accommodate special scenarios such as collections.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Denial of Royalty Disbursement
&lt;ul&gt;
&lt;li&gt;An attacker who has purchased one or more NFTs in a given generation of an NFT family can cause out of gas errors or run time errors for the contract, if they add many spurious royalty sub-accounts with very low royalty split percentages, and then mint more prints of those purchased NFTs, and then repeat that step until the set &lt;code&gt;maxGeneration&lt;&#x2F;code&gt; limit is reached. An NFT trade at the bottom of the hierarchy will then require a lot of code cycles because of the recursive nature of the royalty distribution function. Mitigation: Limit the number of royalty sub-accounts per NFT and impose a royalty split percentage limit.&lt;&#x2F;li&gt;
&lt;li&gt;Following the same approach as above but now targeting the &lt;code&gt;addListNFT&lt;&#x2F;code&gt; function, an attacker can force an out of gas error or run time errors in the &lt;code&gt;executePayment&lt;&#x2F;code&gt; function by listing many NFTs at a low price, and then performing a purchase from another account. Mitigation: Limit the number of NFTs that can be included in one listing.&lt;&#x2F;li&gt;
&lt;li&gt;The creator of the NFT family could set the number of generations too high such that the royalty distribution function could incur and out of gas or run time error because of the recursive nature of the function. Mitigation: Limiting the &lt;code&gt;maxNumberGeneration&lt;&#x2F;code&gt; by the creator.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;General Considerations: The creator of an NFT family must carefully consider the business model for the NFT family and then set the parameters such as maximum number of generations, royalty sub-accounts, number of prints per print, number of NFTs in a listing, and the maximum and minimum royalty split percentage allowed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Phishing Attacks&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;NFT phishing attacks often target the &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; functions by tricking owners of NFTs to sign transactions adding the attacker account as approved for one or all NFTs of the victim. Mitigation: This contract is not vulnerable to these type of phishing attacks because all NFT transfers are sales, and the NFT contract itself is the owner of all NFTs. This means that transfers after a purchase are achieved by setting the new owner in the &lt;code&gt;_approve&lt;&#x2F;code&gt; function. Calling the public &lt;code&gt;approve&lt;&#x2F;code&gt; function will cause the function call to error out because &lt;code&gt;msg.sender&lt;&#x2F;code&gt; of the malicious transaction cannot be the NFT owner.&lt;&#x2F;li&gt;
&lt;li&gt;NFT phishing attack targeting the &lt;code&gt;addListNFT&lt;&#x2F;code&gt; function to trick victim to list one or more NFTs at a very low price and the attacker immediately registering a payment, and executing that payment right away. Mitigation: Implement a waiting period for a purchase can be affected giving the victim time to call the &lt;code&gt;removeListNFT&lt;&#x2F;code&gt; function. In addition, an implementer could require Two-Factor-Authentication either built into the contract or by utilizing an authenticator app such as Google Authenticator built into a wallet software.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Besides the usage of professional security analysis tools, it is also recommended that each implementation performs a security audit of its implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>EIP-721 Metadata Update Extension</title>
        <published>2022-03-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Anders</name><uri>https://github.com/0xanders</uri>
	</author>
	
	<author>
		<name>Lance</name><uri>https://github.com/LanceSnow</uri>
	</author>
	
	<author>
		<name>Shrug</name><email>shrug@emojidao.org</email>
	</author>
	
	<author>
		<name>Nathan</name><email>nathan.gang@gemini.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4906/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip4906-erc-721-erc-1155-metadata-update-extension/8588" />
        

        <id>https://wg-eips.ritovision.com/4906/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4906"
            label="ERC-4906" />
        

        
        

        
        <summary type="html">Add a MetadataUpdate event to EIP-721.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4906/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;. It adds a &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event to EIP-721 tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; contracts emit an event when one of its tokens&#x27; metadata are changed. While tracking changes based on these different events is possible, it is an extra effort for third-party platforms, such as an NFT marketplace, to build individualized solutions for each NFT collection.&lt;&#x2F;p&gt;
&lt;p&gt;Having a standard &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event will make it easy for third-party platforms to timely update the metadata of many NFTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;metadata update extension&lt;&#x2F;strong&gt; is OPTIONAL for EIP-721 contracts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-721 Metadata Update Extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC4906&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when the metadata of a token is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; So that the third-party platforms such as NFT market could&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; timely update the images and related attributes of the NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MetadataUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This event emits when the metadata of a range of tokens is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; So that the third-party platforms such as NFT market could&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; timely update the images and related attributes of the NFTs.    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BatchMetadataUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; or &lt;code&gt;BatchMetadataUpdate&lt;&#x2F;code&gt; event MUST be emitted when the JSON metadata of a token, or a consecutive range of tokens, is changed.&lt;&#x2F;p&gt;
&lt;p&gt;Not emitting &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event is RECOMMENDED when a token is minted.&lt;&#x2F;p&gt;
&lt;p&gt;Not emitting &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event is RECOMMENDED  when a token is burned.&lt;&#x2F;p&gt;
&lt;p&gt;Not emitting &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event is RECOMMENDED  when the tokenURI changes but the JSON metadata does not.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0x49064906&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Different NFTs have different metadata, and metadata generally has multiple fields. &lt;code&gt;bytes data&lt;&#x2F;code&gt; could be used to represents the modified value of metadata.  It is difficult for third-party platforms to identify various types of &lt;code&gt;bytes data&lt;&#x2F;code&gt;, so as to avoid unnecessary complexity, arbitrary metadata is not included in the &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;After capturing the &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; event, a third party can update the metadata with information returned from the &lt;code&gt;tokenURI(uint256 _tokenId)&lt;&#x2F;code&gt; of EIP-721. When a range of token ids is specified, the third party can query each token URI individually.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backwards compatibility issues were found&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC4906.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC4906&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC4906&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;name_, symbol_) &lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC165-supportsInterface}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC165&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x49064906&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;If there is an off-chain modification of metadata, a method that triggers &lt;code&gt;MetadataUpdate&lt;&#x2F;code&gt; can be added, but ensure that the function&#x27;s permission controls are correct.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Rental NFT, an Extension of EIP-721</title>
        <published>2022-03-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Anders</name><uri>https://github.com/0xanders</uri>
	</author>
	
	<author>
		<name>Lance</name><uri>https://github.com/LanceSnow</uri>
	</author>
	
	<author>
		<name>Shrug</name><email>shrug@emojidao.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4907/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/idea-erc-721-user-and-expires-extension/8572" />
        

        <id>https://wg-eips.ritovision.com/4907/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:4907"
            label="ERC-4907" />
        

        
        

        
        <summary type="html">Add a time-limited role with restricted permissions to EIP-721 tokens.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4907/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;. It proposes an additional role (&lt;code&gt;user&lt;&#x2F;code&gt;) which can be granted to addresses, and a time where the role is automatically revoked (&lt;code&gt;expires&lt;&#x2F;code&gt;). The &lt;code&gt;user&lt;&#x2F;code&gt; role represents permission to &quot;use&quot; the NFT, but not the ability to transfer it or set users.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Some NFTs have certain utilities. For example, virtual land can be &quot;used&quot; to build scenes, and NFTs representing game assets can be &quot;used&quot; in-game. In some cases, the owner and user may not always be the same. There may be an owner of the NFT that rents it out to a “user”. The actions that a “user” should be able to take with an NFT would be different from the “owner” (for instance, “users” usually shouldn’t be able to sell ownership of the NFT).  In these situations, it makes sense to have separate roles that identify whether an address represents an “owner” or a “user” and manage permissions to perform actions accordingly.&lt;&#x2F;p&gt;
&lt;p&gt;Some projects already use this design scheme under different names such as “operator” or “controller” but as it becomes more and more prevalent, we need a unified standard to facilitate collaboration amongst all applications.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, applications of this model (such as renting) often demand that user addresses have only temporary access to using the NFT. Normally, this means the owner needs to submit two on-chain transactions, one to list a new address as the new user role at the start of the duration and one to reclaim the user role at the end. This is inefficient in both labor and gas and so an “expires” function is introduced that would facilitate the automatic end of a usage term without the need of a second transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Solidity Interface with NatSpec &amp;amp; OpenZeppelin v4 Interfaces (also available at &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4907&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;IERC4907.sol&quot;&gt;&lt;code&gt;IERC4907.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC4907&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Logged when the user of an NFT is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or expires is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the `user` of an NFT or the `expires` of the `user` is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address for user indicates that there is no user address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the user and expires of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The new user of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  UNIX timestamp, The new user could use the NFT before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the user address of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates that there is no user or the user is expired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the user address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; user address for this NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the user expires of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero value indicates that there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the user expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; user expires for this NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userExpires&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;userOf(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;userExpires(uint256 tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;setUser(uint256 tokenId, address user, uint64 expires)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;UpdateUser&lt;&#x2F;code&gt; event MUST be emitted when a user address is changed or the user expires is changed.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0xad092b5c&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This model is intended to facilitate easy implementation. Here are some of the problems that are solved by this standard:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;clear-rights-assignment&quot;&gt;Clear Rights Assignment&lt;&#x2F;h3&gt;
&lt;p&gt;With Dual “owner” and “user” roles, it becomes significantly easier to manage what lenders and borrowers can and cannot do with the NFT (in other words, their rights). Additionally, owners can control who the user is and it’s easy for other projects to assign their own rights to either the owners or the users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;simple-on-chain-time-management&quot;&gt;Simple On-chain Time Management&lt;&#x2F;h3&gt;
&lt;p&gt;Once a rental period is over, the user role needs to be reset and the “user” has to lose access to the right to use the NFT. This is usually accomplished with a second on-chain transaction but that is gas inefficient and can lead to complications because it’s imprecise. With the &lt;code&gt;expires&lt;&#x2F;code&gt; function, there is no need for another transaction because the “user” is invalidated automatically after the duration is over.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;easy-third-party-integration&quot;&gt;Easy Third-Party Integration&lt;&#x2F;h3&gt;
&lt;p&gt;In the spirit of permission less interoperability, this standard makes it easier for third-party protocols to manage NFT usage rights without permission from the NFT issuer or the NFT application. Once a project has adopted the additional &lt;code&gt;user&lt;&#x2F;code&gt; role and &lt;code&gt;expires&lt;&#x2F;code&gt;, any other project can directly interact with these features and implement their own type of transaction. For example, a PFP NFT using this standard can be integrated into both a rental platform where users can rent the NFT for 30 days AND, at the same time, a mortgage platform where users can use the NFT while eventually buying ownership of the NFT with installment payments. This would all be done without needing the permission of the original PFP project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the specifications section, this standard can be fully EIP-721 compatible by adding an extension function set.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, new functions introduced in this standard have many similarities with the existing functions in EIP-721. This allows developers to easily adopt the standard quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;test-contract&quot;&gt;Test Contract&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;ERC4907Demo&lt;&#x2F;code&gt; Implementation: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4907&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC4907Demo.sol&quot;&gt;&lt;code&gt;ERC4907Demo.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;ERC4907.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC4907Demo&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC4907&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;     ERC4907&lt;&#x2F;span&gt;&lt;span&gt;(&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&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;test-code&quot;&gt;Test Code&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4907&#x2F;.&#x2F;assets&#x2F;test&#x2F;test.js&quot;&gt;test.js&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; assert&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chai&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ERC4907Demo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; artifacts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC4907Demo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;should set user to Bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get initial balances of first and second account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; Alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; Bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ERC4907Demo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;deployed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; demo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; instance&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;        await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; demo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Alice&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;floor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Date&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; demo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;setUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Bob&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BigInt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; demo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;userOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;            user_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 class=&quot;z-variable z-other&quot;&gt;            Bob&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;User of NFT 1 should be Bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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 class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; demo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;            owner_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 class=&quot;z-variable z-other&quot;&gt;            Alice&lt;&#x2F;span&gt;&lt;span&gt; ,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Owner of NFT 1 should be Alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&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&gt;}&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;run in Terminal：&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;truffle test .&#x2F;test&#x2F;test.js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Implementation: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4907&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC4907.sol&quot;&gt;&lt;code&gt;ERC4907.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC4907.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC4907&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC4907&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UserInfo&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of user role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unix timestamp, user expires&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 class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; UserInfo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; _users&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;     ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&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&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set the user and expires of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The new user of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  UNIX timestamp, The new user could use the NFT before expires&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_isApprovedOrOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC4907: transfer caller is not owner nor approved&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        UserInfo &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; info &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;  _users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        info&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;user &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        info&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; expires&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the user address of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates that there is no user or the user is expired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the user address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; user address for this NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;  block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt;  _users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the user expires of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero value indicates that there is no user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the user expires for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; user expires for this NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userExpires&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;expires&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC165-supportsInterface}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;IERC4907&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;interfaceId &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;interfaceId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-variable z-language&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_beforeTokenTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;from &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span&gt; to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; _users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;user &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            delete&lt;&#x2F;span&gt;&lt;span&gt; _users&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdateUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&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;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standard can completely protect the rights of the owner, the owner can change the NFT user and expires at any time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC-721 Entitlement Extension</title>
        <published>2022-03-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	<author>
		<name>Tim Daubenschütz</name><uri>https://github.com/TimDaub</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5380/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/pr-5380-eip-4907-alternative-design/10190" />
        

        <id>https://wg-eips.ritovision.com/5380/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5380"
            label="ERC-5380" />
        

        
        

        
        <summary type="html">Allows token owners to grant the ability for others to use specific properties of those tokens</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5380/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a new interface that allows &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; token owners to grant limited usage of those tokens to other addresses.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There are many scenarios in which it makes sense for the owner of a token to grant certain properties to another address. One use case is renting tokens. If the token in question represents a trading card in an on-chain TCG (trading card game), one might want to be able to use that card in the game without having to actually buy it. Therefore, the owner might grant the renter the &quot;property&quot; of it being able to be played in the TCG. However, this property should only be able to be assigned to one person at a time, otherwise a contract could simply &quot;rent&quot; the card to everybody. If the token represents usage rights instead, the property of being allowed to use the associated media does not need such a restriction, and there is no reason that the property should be as scarce as the token.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot; and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;base&quot;&gt;Base&lt;&#x2F;h3&gt;
&lt;p&gt;Compliant entitlement contracts MUST implement the following Solidity interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380Entitlement&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the amount of entitlement a user has changes. If user is the zero address, then the user is the owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EntitlementChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             Set the user associated with the given ERC-721 token as long as the owner is msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                SHOULD NOT revert if the owner is not msg.sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The user to grant the entitlement to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The property to grant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The tokenId to grant the properties of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; entitle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             Get the maximum number of users that can receive this entitlement&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The contract to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The tokenId to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; maxEntitlements&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             Get the user associated with the given contract and tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                Defaults to maxEntitlements(contract, tokenId) assigned to contract.ownerOf(tokenId)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The user to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The contract to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The tokenId to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; entitlementOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amt&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;supportsInterface&lt;&#x2F;code&gt; MUST return true when called with &lt;code&gt;ERC5380Entitlement&lt;&#x2F;code&gt;&#x27;s interface ID.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enumerable-extension&quot;&gt;Enumerable Extension&lt;&#x2F;h3&gt;
&lt;p&gt;This OPTIONAL Solidity interface is RECOMMENDED.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380EntitlementEnumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380Entitlement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Also implicitly supports ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Enumerate tokens with nonzero entitlement assigned to a user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            Throws if the index is out of bounds or if user == address(0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    The user to query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   A counter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; entitlementOfUserByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;supportsInterface&lt;&#x2F;code&gt; MUST return true when called with &lt;code&gt;ERC5380EntitlementEnumerable&lt;&#x2F;code&gt;&#x27;s interface ID.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;metadata-extension&quot;&gt;Metadata Extension&lt;&#x2F;h3&gt;
&lt;p&gt;This OPTIONAL Solidity interface is RECOMMENDED.&lt;&#x2F;p&gt;
&lt;p&gt;This extension uses &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1046&#x2F;&quot;&gt;ERC-1046&lt;&#x2F;a&gt; for &lt;code&gt;tokenURI&lt;&#x2F;code&gt; compatibility.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380EntitlementMetadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380Entitlement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Also implicitly supports ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             ERC-1046 token URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                See ERC-1046 and the metadata schema below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;supportsInterface&lt;&#x2F;code&gt; MUST return true when called with &lt;code&gt;ERC5380EntitlementMetadata&lt;&#x2F;code&gt;&#x27;s interface ID.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;interoperability-metadata-extension&quot;&gt;Interoperability Metadata Extension&lt;&#x2F;h4&gt;
&lt;p&gt;ERC-1046&#x27;s &lt;code&gt;InteroperabilityMetadata&lt;&#x2F;code&gt; is extended with the following TypeScript interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * ERC-5380&amp;#39;s extension to ERC-1046&amp;#39;s Interoperability metadata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380InteroperabilityMetadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InteroperabilityMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This MUST be true if this is ERC-5380 Token Metadata, otherwise, this MUST be omitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Setting this to true indicates to wallets that the address should be treated as an ERC-5380 entitlement.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    erc5380&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; undefined&lt;&#x2F;span&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;h4 id=&quot;tokenuri-metadata-schema&quot;&gt;&lt;code&gt;tokenURI&lt;&#x2F;code&gt; Metadata Schema&lt;&#x2F;h4&gt;
&lt;p&gt;The resolved &lt;code&gt;tokenURI&lt;&#x2F;code&gt; data MUST conform to the following TypeScript interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * ERC-5380 Asset Metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Can be extended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380TokenMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Interoperabiliy, to differentiate between different types of tokens and their corresponding URIs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    interop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC5380InteroperabilityMetadata&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The name of the ERC-5380 token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The symbol of the ERC-5380 token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    symbol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Provides a short one-paragraph description of the ERC-5380 token, without any markup or newlines.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * One or more URIs each pointing to a resource with mime type `image&#x2F;*` that represents this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Images SHOULD have an aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    images&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * One or more URIs each pointing to a resource with mime type `image&#x2F;*` that represent an icon for this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels, and MUST have a height equal to its width&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Images MUST have an aspect ratio of 1:1, and use a transparent background&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    icons&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; are unsupported as partial ownership is much more complex to track than boolean ownership.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backward compatibility issues were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The security considerations of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1046&#x2F;&quot;&gt;ERC-1046&lt;&#x2F;a&gt; apply.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Beacon chain push withdrawals as operations</title>
        <published>2022-03-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4895/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4895-beacon-chain-withdrawals-as-system-level-operations/8568" />
        

        <id>https://wg-eips.ritovision.com/4895/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:4895"
            label="EIP-4895" />
        

        
        

        
        <summary type="html">Support validator withdrawals from the beacon chain to the EVM via a new &quot;system-level&quot; operation type.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4895/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce a system-level &quot;operation&quot; to support validator withdrawals that are &quot;pushed&quot; from the beacon chain to the EVM.&lt;&#x2F;p&gt;
&lt;p&gt;These operations create unconditional balance increases to the specified recipients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP provides a way for validator withdrawals made on the beacon chain to enter into the EVM.
The architecture is &quot;push&quot;-based, rather than &quot;pull&quot;-based, where withdrawals are required to be processed in the execution layer as soon as they are dequeued from the consensus layer.&lt;&#x2F;p&gt;
&lt;p&gt;Withdrawals are represented as a new type of object in the execution payload -- an &quot;operation&quot; -- that separates the withdrawals feature from user-level transactions.
This approach is more involved than the prior approach introducing a new transaction type but it cleanly separates this &quot;system-level&quot; operation from regular transactions.
The separation simplifies testing (so facilitates security) by reducing interaction effects generated by mixing this system-level concern with user data.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, this approach is more complex than &quot;pull&quot;-based alternatives with respect to the core protocol but does provide tighter integration of a critical feature into the protocol itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;constants&lt;&#x2F;th&gt;&lt;th&gt;value&lt;&#x2F;th&gt;&lt;th&gt;units&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_TIMESTAMP&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1681338455&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Beginning with the execution timestamp &lt;code&gt;FORK_TIMESTAMP&lt;&#x2F;code&gt;, execution clients &lt;strong&gt;MUST&lt;&#x2F;strong&gt; introduce the following extensions to payload validation and processing:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-level-operation-withdrawal&quot;&gt;System-level operation: withdrawal&lt;&#x2F;h3&gt;
&lt;p&gt;Define a new payload-level object called a &lt;code&gt;withdrawal&lt;&#x2F;code&gt; that describes withdrawals that have been validated at the consensus layer.
&lt;code&gt;Withdrawal&lt;&#x2F;code&gt;s are syntactically similar to a user-level transaction but live in a different domain than user-level transactions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Withdrawal&lt;&#x2F;code&gt;s provide key information from the consensus layer:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;a monotonically increasing &lt;code&gt;index&lt;&#x2F;code&gt;, starting from 0, as a &lt;code&gt;uint64&lt;&#x2F;code&gt; value that increments by 1 per withdrawal to uniquely identify each withdrawal&lt;&#x2F;li&gt;
&lt;li&gt;the &lt;code&gt;validator_index&lt;&#x2F;code&gt; of the validator, as a &lt;code&gt;uint64&lt;&#x2F;code&gt; value, on the consensus layer the withdrawal corresponds to&lt;&#x2F;li&gt;
&lt;li&gt;a recipient for the withdrawn ether &lt;code&gt;address&lt;&#x2F;code&gt; as a 20-byte value&lt;&#x2F;li&gt;
&lt;li&gt;a nonzero &lt;code&gt;amount&lt;&#x2F;code&gt; of ether given in Gwei (1e9 wei) as a &lt;code&gt;uint64&lt;&#x2F;code&gt; value.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: the &lt;code&gt;index&lt;&#x2F;code&gt; for each withdrawal is a global counter spanning the entire sequence of withdrawals.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Withdrawal&lt;&#x2F;code&gt; objects are serialized as a RLP list according to the schema: &lt;code&gt;[index, validator_index, address, amount]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;new-field-in-the-execution-payload-withdrawals&quot;&gt;New field in the execution payload: withdrawals&lt;&#x2F;h3&gt;
&lt;p&gt;The execution payload gains a new field for the &lt;code&gt;withdrawals&lt;&#x2F;code&gt; which is an RLP list of &lt;code&gt;Withdrawal&lt;&#x2F;code&gt; data.&lt;&#x2F;p&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;withdrawal_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;index_0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; validator_index_0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; address_0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount_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&gt;withdrawal_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;index_1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; validator_index_1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; address_1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount_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&gt;withdrawals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;withdrawal_0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; withdrawal_1&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 new field is encoded after the existing fields in the execution payload structure and is considered part of the execution payload&#x27;s body.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;execution_payload_rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; RLP&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; transactions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; withdrawals&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;execution_payload_body_rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; RLP&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;transactions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; withdrawals&lt;&#x2F;span&gt;&lt;span&gt;]&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;NOTE: the empty list in this schema is due to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt; that sets the &lt;code&gt;ommers&lt;&#x2F;code&gt; value to a fixed constant.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;new-field-in-the-execution-payload-header-withdrawals-root&quot;&gt;New field in the execution payload header: withdrawals root&lt;&#x2F;h3&gt;
&lt;p&gt;The execution payload header gains a new field committing to the &lt;code&gt;withdrawals&lt;&#x2F;code&gt; in the execution payload.&lt;&#x2F;p&gt;
&lt;p&gt;This commitment is constructed identically to the transactions root in the existing execution payload header by inserting
each withdrawal into a Merkle-Patricia trie keyed by index in the list of &lt;code&gt;withdrawals&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compute_trie_root_from_indexed_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&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&gt;    trie&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Trie&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; obj&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; obj&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; trie&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;root&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;execution_payload_header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdrawals_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; compute_trie_root_from_indexed_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;execution_payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdrawals&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 execution payload header is extended with a new field containing the 32 byte root of the trie committing to the list of withdrawals provided in a given execution payload.&lt;&#x2F;p&gt;
&lt;p&gt;To illustrate:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;execution_payload_header_rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; RLP&lt;&#x2F;span&gt;&lt;span&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&gt;  parent_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ommers hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  coinbase&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  state_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  txs_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  receipts_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  logs_bloom&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; difficulty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  number&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  gas_used&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  timestamp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  extradata&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  prev_randao&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0000000000000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  base_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  withdrawals_root&lt;&#x2F;span&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;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NOTE: field names and constant value in this example reflect &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4399&#x2F;&quot;&gt;EIP-4399&lt;&#x2F;a&gt;. Refer to those EIPs for further information.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-payload-validity&quot;&gt;Execution payload validity&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming the execution payload is well-formatted, the execution client has an additional payload validation to ensure that the &lt;code&gt;withdrawals_root&lt;&#x2F;code&gt; matches the expected value given the list in the payload.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; execution_payload_header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdrawals_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; compute_trie_root_from_indexed_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;execution_payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withdrawals&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;state-transition&quot;&gt;State transition&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;withdrawals&lt;&#x2F;code&gt; in an execution payload are processed &lt;strong&gt;after&lt;&#x2F;strong&gt; any user-level transactions are applied.&lt;&#x2F;p&gt;
&lt;p&gt;For each &lt;code&gt;withdrawal&lt;&#x2F;code&gt; in the list of &lt;code&gt;execution_payload.withdrawals&lt;&#x2F;code&gt;, the implementation increases the balance of the &lt;code&gt;address&lt;&#x2F;code&gt; specified by the &lt;code&gt;amount&lt;&#x2F;code&gt; given.&lt;&#x2F;p&gt;
&lt;p&gt;Recall that the &lt;code&gt;amount&lt;&#x2F;code&gt; is given in units of Gwei so a conversion to units of wei must be performed when working with account balances in the execution state.&lt;&#x2F;p&gt;
&lt;p&gt;This balance change is unconditional and &lt;strong&gt;MUST&lt;&#x2F;strong&gt; not fail.&lt;&#x2F;p&gt;
&lt;p&gt;This operation has no associated gas costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-not-a-new-transaction-type&quot;&gt;Why not a new transaction type?&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP suggests a new type of object -- the &quot;withdrawal operation&quot; -- as it has special semantics different from other existing types of EVM transactions.&lt;&#x2F;p&gt;
&lt;p&gt;Operations are initiated by the overall system, rather than originating from end users like typical transactions.&lt;&#x2F;p&gt;
&lt;p&gt;An entirely new type of object firewalls off generic EVM execution from this type of processing to simplify testing and security review of withdrawals.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-no-gas-costs-for-the-withdrawal-type&quot;&gt;Why no (gas) costs for the withdrawal type?&lt;&#x2F;h3&gt;
&lt;p&gt;The maximum number of withdrawals that can reach the execution layer at a given time is bounded (enforced by the consensus layer) and this limit has been chosen so that
any execution layer operational costs are negligible in the context of the broader payload execution.&lt;&#x2F;p&gt;
&lt;p&gt;This bound applies to both computational cost (only a few balance updates in the state) and storage&#x2F;networking cost as the additional payload footprint is kept small (current parameterizations put the additional overhead at ~1% of current average payload size).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-only-balance-updates-no-general-evm-execution&quot;&gt;Why only balance updates? No general EVM execution?&lt;&#x2F;h3&gt;
&lt;p&gt;More general processing introduces the risk of failures, which complicates accounting on the beacon chain.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP suggests a route for withdrawals that provides most of the benefits for a minimum of the (complexity) cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Consensus-layer validation of withdrawal transactions is critical to ensure that the proper amount of ETH is withdrawn back into the execution layer.
This consensus-layer to execution-layer ETH transfer does not have a current analog in the EVM and thus deserves very high security scrutiny.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Shard Blob Transactions</title>
        <published>2022-02-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	<author>
		<name>Diederik Loerakker</name><uri>https://github.com/protolambda</uri>
	</author>
	
	<author>
		<name>George Kadianakis</name><uri>https://github.com/asn-d6</uri>
	</author>
	
	<author>
		<name>Matt Garnett</name><uri>https://github.com/lightclient</uri>
	</author>
	
	<author>
		<name>Mofi Taiwo</name><uri>https://github.com/Inphi</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4844/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4844-shard-blob-transactions/8430" />
        

        <id>https://wg-eips.ritovision.com/4844/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:4844"
            label="EIP-4844" />
        

        
        

        
        <summary type="html">Shard Blob Transactions scale data-availability of Ethereum in a simple, forwards-compatible manner.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4844/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce a new transaction format for &quot;blob-carrying transactions&quot; which contain a large amount of data that cannot be
accessed by EVM execution, but whose commitment can be accessed.
The format is intended to be fully compatible with the format that will be used in full sharding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Rollups are in the short and medium term, and possibly in the long term, the only trustless scaling solution for Ethereum.
Transaction fees on L1 have been very high for months and there is greater urgency in doing anything required to help facilitate an ecosystem-wide move to rollups.
Rollups are significantly reducing fees for many Ethereum users: Optimism and Arbitrum frequently provide fees that are ~3-8x lower than the Ethereum base layer itself,
and ZK rollups, which have better data compression and can avoid including signatures, have fees ~40-100x lower than the base layer.&lt;&#x2F;p&gt;
&lt;p&gt;However, even these fees are too expensive for many users. The long-term solution to the long-term inadequacy of rollups
by themselves has always been data sharding, which would add ~16 MB per block of dedicated data space to the chain that rollups could use.
However, data sharding will still take a considerable amount of time to finish implementing and deploying.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP provides a stop-gap solution until that point by implementing the &lt;em&gt;transaction format&lt;&#x2F;em&gt; that would be used in sharding,
but not actually sharding those transactions. Instead, the data from this transaction format is simply part of the beacon chain and is fully downloaded
by all consensus nodes (but can be deleted after only a relatively short delay).
Compared to full data sharding, this EIP has a reduced cap on the number of these transactions that can be included, corresponding to a target of ~0.375 MB per block and a limit of ~0.75 MB.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOB_TX_TYPE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes1(0x03)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BYTES_PER_FIELD_ELEMENT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FIELD_ELEMENTS_PER_BLOB&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;4096&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLS_MODULUS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;52435875175126190479447740508185965837690552500527637822603658699938581184513&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;VERSIONED_HASH_VERSION_KZG&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes1(0x01)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;POINT_EVALUATION_PRECOMPILE_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes20(0x0A)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;POINT_EVALUATION_PRECOMPILE_GAS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;50000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;786432&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;393216&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_BASE_FEE_PER_BLOB_GAS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;3338477&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;GAS_PER_BLOB&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**17&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;HASH_OPCODE_BYTE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes1(0x49)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;HASH_OPCODE_GAS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;4de1d156c78b555421b72d6067c73b614ab55584&#x2F;configs&#x2F;mainnet.yaml#L148&quot;&gt;&lt;code&gt;MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;4096&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;type-aliases&quot;&gt;Type aliases&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type&lt;&#x2F;th&gt;&lt;th&gt;Base type&lt;&#x2F;th&gt;&lt;th&gt;Additional checks&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Blob&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;VersionedHash&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KZGCommitment&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Perform IETF BLS signature &quot;KeyValidate&quot; check but do allow the identity point&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KZGProof&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;Bytes48&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Same as for &lt;code&gt;KZGCommitment&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;cryptographic-helpers&quot;&gt;Cryptographic Helpers&lt;&#x2F;h3&gt;
&lt;p&gt;Throughout this proposal we use cryptographic methods and classes defined in the corresponding &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;86fb82b221474cc89387fa6436806507b3849d88&#x2F;specs&#x2F;deneb&quot;&gt;consensus 4844 specs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Specifically, we use the following methods from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;86fb82b221474cc89387fa6436806507b3849d88&#x2F;specs&#x2F;deneb&#x2F;polynomial-commitments.md&quot;&gt;&lt;code&gt;polynomial-commitments.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;86fb82b221474cc89387fa6436806507b3849d88&#x2F;specs&#x2F;deneb&#x2F;polynomial-commitments.md#verify_kzg_proof&quot;&gt;&lt;code&gt;verify_kzg_proof()&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;86fb82b221474cc89387fa6436806507b3849d88&#x2F;specs&#x2F;deneb&#x2F;polynomial-commitments.md#verify_blob_kzg_proof_batch&quot;&gt;&lt;code&gt;verify_blob_kzg_proof_batch()&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;helpers&quot;&gt;Helpers&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; kzg_to_versioned_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; KZGCommitment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; VersionedHash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; VERSIONED_HASH_VERSION_KZG&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;:&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;Approximates &lt;code&gt;factor * e ** (numerator &#x2F; denominator)&lt;&#x2F;code&gt; using Taylor expansion:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; denominator&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; numerator_accum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;numerator_accum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; numerator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;denominator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;blob-transaction&quot;&gt;Blob transaction&lt;&#x2F;h3&gt;
&lt;p&gt;We introduce a new type of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction, &quot;blob transaction&quot;, where the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; is &lt;code&gt;BLOB_TX_TYPE&lt;&#x2F;code&gt; and the &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; is the RLP serialization of the following &lt;code&gt;TransactionPayloadBody&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes, y_parity, r, s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The fields &lt;code&gt;chain_id&lt;&#x2F;code&gt;, &lt;code&gt;nonce&lt;&#x2F;code&gt;, &lt;code&gt;max_priority_fee_per_gas&lt;&#x2F;code&gt;, &lt;code&gt;max_fee_per_gas&lt;&#x2F;code&gt;, &lt;code&gt;gas_limit&lt;&#x2F;code&gt;, &lt;code&gt;value&lt;&#x2F;code&gt;, &lt;code&gt;data&lt;&#x2F;code&gt;, and &lt;code&gt;access_list&lt;&#x2F;code&gt; follow the same semantics as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The field &lt;code&gt;to&lt;&#x2F;code&gt; deviates slightly from the semantics with the exception that it MUST NOT be &lt;code&gt;nil&lt;&#x2F;code&gt; and therefore must always represent a 20-byte address. This means that blob transactions cannot have the form of a create transaction.&lt;&#x2F;p&gt;
&lt;p&gt;The field &lt;code&gt;max_fee_per_blob_gas&lt;&#x2F;code&gt; is a &lt;code&gt;uint256&lt;&#x2F;code&gt; and the field &lt;code&gt;blob_versioned_hashes&lt;&#x2F;code&gt; represents a list of hash outputs from &lt;code&gt;kzg_to_versioned_hash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; for this transaction is &lt;code&gt;rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;signature&quot;&gt;Signature&lt;&#x2F;h4&gt;
&lt;p&gt;The signature values &lt;code&gt;y_parity&lt;&#x2F;code&gt;, &lt;code&gt;r&lt;&#x2F;code&gt;, and &lt;code&gt;s&lt;&#x2F;code&gt; are calculated by constructing a secp256k1 signature over the following digest:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;keccak256(BLOB_TX_TYPE || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes]))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;header-extension&quot;&gt;Header extension&lt;&#x2F;h3&gt;
&lt;p&gt;The current header encoding is extended with two new 64-bit unsigned integer fields:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blob_gas_used&lt;&#x2F;code&gt; is the total amount of blob gas consumed by the transactions within the block.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; is a running total of blob gas consumed in excess of the target, prior to the block. Blocks with above-target blob gas consumption increase this value, blocks with below-target blob gas consumption decrease it (bounded at 0).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The resulting RLP encoding of the header is therefore:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    parent_hash,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, # ommers hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    coinbase,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state_root,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    txs_root,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    receipts_root,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    logs_bloom,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    0, # difficulty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    number,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gas_limit,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gas_used,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    timestamp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    extradata,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prev_randao,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    0x0000000000000000, # nonce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base_fee_per_gas,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    withdrawals_root,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blob_gas_used,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    excess_blob_gas,&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 value of &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; can be calculated using the parent header.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calc_excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the first post-fork block, both &lt;code&gt;parent.blob_gas_used&lt;&#x2F;code&gt; and &lt;code&gt;parent.excess_blob_gas&lt;&#x2F;code&gt; are evaluated as &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-accounting&quot;&gt;Gas accounting&lt;&#x2F;h3&gt;
&lt;p&gt;We introduce blob gas as a new type of gas. It is independent of normal gas and follows its own targeting rule, similar to EIP-1559.
We use the &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; header field to store persistent data needed to compute the blob gas base fee. For now, only blobs are priced in blob gas.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calc_blob_fee&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;header&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; get_total_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; get_base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_total_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; GAS_PER_BLOB&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_versioned_hashes&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;header&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Header&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fake_exponential&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        MIN_BASE_FEE_PER_BLOB_GAS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        BLOB_BASE_FEE_UPDATE_FRACTION&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 block validity conditions are modified to include blob gas checks (see the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;#execution-layer-validation&quot;&gt;Execution layer validation&lt;&#x2F;a&gt; section below).&lt;&#x2F;p&gt;
&lt;p&gt;The actual &lt;code&gt;blob_fee&lt;&#x2F;code&gt; as calculated via &lt;code&gt;calc_blob_fee&lt;&#x2F;code&gt; is deducted from the sender balance before transaction execution and burned, and is not refunded in case of transaction failure.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;opcode-to-get-versioned-hashes&quot;&gt;Opcode to get versioned hashes&lt;&#x2F;h3&gt;
&lt;p&gt;We add an instruction &lt;code&gt;BLOBHASH&lt;&#x2F;code&gt; (with opcode &lt;code&gt;HASH_OPCODE_BYTE&lt;&#x2F;code&gt;) which reads &lt;code&gt;index&lt;&#x2F;code&gt; from the top of the stack
as big-endian &lt;code&gt;uint256&lt;&#x2F;code&gt;, and replaces it on the stack with &lt;code&gt;tx.blob_versioned_hashes[index]&lt;&#x2F;code&gt;
if &lt;code&gt;index &amp;lt; len(tx.blob_versioned_hashes)&lt;&#x2F;code&gt;, and otherwise with a zeroed &lt;code&gt;bytes32&lt;&#x2F;code&gt; value.
The opcode has a gas cost of &lt;code&gt;HASH_OPCODE_GAS&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;point-evaluation-precompile&quot;&gt;Point evaluation precompile&lt;&#x2F;h3&gt;
&lt;p&gt;Add a precompile at &lt;code&gt;POINT_EVALUATION_PRECOMPILE_ADDRESS&lt;&#x2F;code&gt; that verifies a KZG proof which claims that a blob
(represented by a commitment) evaluates to a given value at a given point.&lt;&#x2F;p&gt;
&lt;p&gt;The precompile costs &lt;code&gt;POINT_EVALUATION_PRECOMPILE_GAS&lt;&#x2F;code&gt; and executes the following logic:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; point_evaluation_precompile&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Bytes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Also verify that the provided commitment matches the provided versioned_hash.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The data is encoded as follows: versioned_hash | z | y | commitment | proof | with z and y being padded 32 byte big endian values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    versioned_hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;96&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    commitment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;96&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;144&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;144&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;192&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify commitment matches versioned_hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; kzg_to_versioned_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; versioned_hash&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verify KZG proof with z and y in big endian format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; verify_kzg_proof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;commitment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return FIELD_ELEMENTS_PER_BLOB and BLS_MODULUS as padded 32 byte big endian values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; Bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;U256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;FIELD_ELEMENTS_PER_BLOB&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_be_bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; U256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;BLS_MODULUS&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_be_bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&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 precompile MUST reject non-canonical field elements (i.e. provided field elements MUST be strictly less than &lt;code&gt;BLS_MODULUS&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consensus-layer-validation&quot;&gt;Consensus layer validation&lt;&#x2F;h3&gt;
&lt;p&gt;On the consensus layer the blobs are referenced, but not fully encoded, in the beacon block body.
Instead of embedding the full contents in the body, the blobs are propagated separately, as &quot;sidecars&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;This &quot;sidecar&quot; design provides forward compatibility for further data increases by black-boxing &lt;code&gt;is_data_available()&lt;&#x2F;code&gt;:
with full sharding &lt;code&gt;is_data_available()&lt;&#x2F;code&gt; can be replaced by data-availability-sampling (DAS) thus avoiding all blobs being downloaded by all beacon nodes on the network.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the consensus layer is tasked with persisting the blobs for data availability, the execution layer is not.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository defines the following consensus layer changes involved in this EIP:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Beacon chain: process updated beacon blocks and ensure blobs are available.&lt;&#x2F;li&gt;
&lt;li&gt;P2P network: gossip and sync updated beacon block types and new blob sidecars.&lt;&#x2F;li&gt;
&lt;li&gt;Honest validator: produce beacon blocks with blobs; sign and publish the associated blob sidecars.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;execution-layer-validation&quot;&gt;Execution layer validation&lt;&#x2F;h3&gt;
&lt;p&gt;On the execution layer, the block validity conditions are extended as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validate_block&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check that the excess blob gas was updated correctly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;excess_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; calc_excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&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&gt;    blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transactions&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; modify the check for sufficient balance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        max_total_fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; get_tx_type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BLOB_TX_TYPE&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            max_total_fee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; get_total_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; signer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; max_total_fee&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 class=&quot;z-constant&quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; add validity logic specific to blob txs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; get_tx_type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BLOB_TX_TYPE&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; there must be at least one blob&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_versioned_hashes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; all versioned blob hashes must start with VERSIONED_HASH_VERSION_KZG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_versioned_hashes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                assert&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; VERSIONED_HASH_VERSION_KZG&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ensure that the user was willing to at least pay the current blob base fee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; get_base_fee_per_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keep track of total blob gas spent in the block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; get_total_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tx&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ensure the total blob gas spent is at most equal to the limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_BLOB_GAS_PER_BLOCK&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ensure blob_gas_used matches header&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;blob_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; blob_gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;networking&quot;&gt;Networking&lt;&#x2F;h3&gt;
&lt;p&gt;Blob transactions have two network representations. During transaction gossip responses (&lt;code&gt;PooledTransactions&lt;&#x2F;code&gt;), the EIP-2718 &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; of the blob transaction is wrapped to become:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp([tx_payload_body, blobs, commitments, proofs])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each of these elements are defined as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tx_payload_body&lt;&#x2F;code&gt; - is the &lt;code&gt;TransactionPayloadBody&lt;&#x2F;code&gt; of standard EIP-2718 &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4844&#x2F;#blob-transaction&quot;&gt;blob transaction&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;blobs&lt;&#x2F;code&gt; - list of &lt;code&gt;Blob&lt;&#x2F;code&gt; items&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;commitments&lt;&#x2F;code&gt; - list of &lt;code&gt;KZGCommitment&lt;&#x2F;code&gt; of the corresponding &lt;code&gt;blobs&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;proofs&lt;&#x2F;code&gt; - list of &lt;code&gt;KZGProof&lt;&#x2F;code&gt; of the corresponding &lt;code&gt;blobs&lt;&#x2F;code&gt; and &lt;code&gt;commitments&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The node MUST validate &lt;code&gt;tx_payload_body&lt;&#x2F;code&gt; and verify the wrapped data against it. To do so, ensure that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There are an equal number of &lt;code&gt;tx_payload_body.blob_versioned_hashes&lt;&#x2F;code&gt;, &lt;code&gt;blobs&lt;&#x2F;code&gt;, &lt;code&gt;commitments&lt;&#x2F;code&gt;, and &lt;code&gt;proofs&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The KZG &lt;code&gt;commitments&lt;&#x2F;code&gt; hash to the versioned hashes, i.e. &lt;code&gt;kzg_to_versioned_hash(commitments[i]) == tx_payload_body.blob_versioned_hashes[i]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The KZG &lt;code&gt;commitments&lt;&#x2F;code&gt; match the corresponding &lt;code&gt;blobs&lt;&#x2F;code&gt; and &lt;code&gt;proofs&lt;&#x2F;code&gt;. (Note: this can be optimized using &lt;code&gt;verify_blob_kzg_proof_batch&lt;&#x2F;code&gt;, with a proof for a
random evaluation at a point derived from the commitment and blob data for each blob)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For body retrieval responses (&lt;code&gt;BlockBodies&lt;&#x2F;code&gt;), the standard EIP-2718 blob transaction &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; is used.&lt;&#x2F;p&gt;
&lt;p&gt;Nodes MUST NOT automatically broadcast blob transactions to their peers.
Instead, those transactions are only announced using &lt;code&gt;NewPooledTransactionHashes&lt;&#x2F;code&gt; messages, and can then be manually requested via &lt;code&gt;GetPooledTransactions&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;on-the-path-to-sharding&quot;&gt;On the path to sharding&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP introduces blob transactions in the same format in which they are expected to exist in the final sharding specification.
This provides a temporary but significant scaling relief for rollups by allowing them to initially scale to 0.375 MB per slot,
with a separate fee market allowing fees to be very low while usage of this system is limited.&lt;&#x2F;p&gt;
&lt;p&gt;The core goal of rollup scaling stopgaps is to provide temporary scaling relief,
without imposing extra development burdens on rollups to take advantage of this relief.
Today, rollups use calldata. In the future, rollups will have no choice but to use sharded data (also called &quot;blobs&quot;)
because sharded data will be much cheaper.
Hence, rollups cannot avoid making a large upgrade to how they process data at least once along the way.
But what we &lt;em&gt;can&lt;&#x2F;em&gt; do is ensure that rollups need to &lt;em&gt;only&lt;&#x2F;em&gt; upgrade once.
This immediately implies that there are exactly two possibilities for a stopgap: (i) reducing the gas costs of existing calldata,
and (ii) bringing forward the format that will be used for sharded data, but not yet actually sharding it.
Previous EIPs were all a solution of category (i); this EIP is a solution of category (ii).&lt;&#x2F;p&gt;
&lt;p&gt;The main tradeoff in designing this EIP is that of implementing more now versus having to implement more later:
do we implement 25% of the work on the way to full sharding, or 50%, or 75%?&lt;&#x2F;p&gt;
&lt;p&gt;The work that is already done in this EIP includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A new transaction type, of the exact same format that will need to exist in &quot;full sharding&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;All&lt;&#x2F;em&gt; of the execution-layer logic required for full sharding&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;All&lt;&#x2F;em&gt; of the execution &#x2F; consensus cross-verification logic required for full sharding&lt;&#x2F;li&gt;
&lt;li&gt;Layer separation between &lt;code&gt;BeaconBlock&lt;&#x2F;code&gt; verification and data availability sampling blobs&lt;&#x2F;li&gt;
&lt;li&gt;Most of the &lt;code&gt;BeaconBlock&lt;&#x2F;code&gt; logic required for full sharding&lt;&#x2F;li&gt;
&lt;li&gt;A self-adjusting independent base fee for blobs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The work that remains to be done to get to full sharding includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A low-degree extension of the &lt;code&gt;commitments&lt;&#x2F;code&gt; in the consensus layer to allow 2D sampling&lt;&#x2F;li&gt;
&lt;li&gt;An actual implementation of data availability sampling&lt;&#x2F;li&gt;
&lt;li&gt;PBS (proposer&#x2F;builder separation), to avoid requiring individual validators to process 32 MB of data in one slot&lt;&#x2F;li&gt;
&lt;li&gt;Proof of custody or similar in-protocol requirement for each validator to verify a particular part of the sharded data in each block&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This EIP also sets the stage for longer-term protocol cleanups. For example, its (cleaner) gas base fee update rule could be applied to the primary basefee calculation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-rollups-would-function&quot;&gt;How rollups would function&lt;&#x2F;h3&gt;
&lt;p&gt;Instead of putting rollup block data in transaction calldata, rollups would expect rollup block submitters
to put the data into blobs. This guarantees availability (which is what rollups need) but would be much cheaper than calldata.
Rollups need data to be available once, long enough to ensure honest actors can construct the rollup state, but not forever.&lt;&#x2F;p&gt;
&lt;p&gt;Optimistic rollups only need to actually provide the underlying data when fraud proofs are being submitted.
The fraud proof can verify the transition in smaller steps, loading at most a few values of the blob at a time through calldata.
For each value it would provide a KZG proof and use the point evaluation precompile to verify the value against the versioned hash that was submitted before,
and then perform the fraud proof verification on that data as is done today.&lt;&#x2F;p&gt;
&lt;p&gt;ZK rollups would provide two commitments to their transaction or state delta data:
the blob commitment (which the protocol ensures points to available data) and the ZK rollup&#x27;s own commitment using whatever proof system the rollup uses internally.
They would use a proof of equivalence protocol, using the point evaluation precompile,
to prove that the two commitments refer to the same data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;versioned-hashes-precompile-return-data&quot;&gt;Versioned hashes &amp;amp; precompile return data&lt;&#x2F;h3&gt;
&lt;p&gt;We use versioned hashes (rather than commitments) as references to blobs in the execution layer to ensure forward compatibility with future changes.
For example, if we need to switch to Merkle trees + STARKs for quantum-safety reasons, then we would add a new version,
allowing the point evaluation precompile to work with the new format.
Rollups would not have to make any EVM-level changes to how they work;
sequencers would simply have to switch over to using a new transaction type at the appropriate time.&lt;&#x2F;p&gt;
&lt;p&gt;However, the point evaluation happens inside a finite field, and it is only well defined if the field modulus is known. Smart contracts could contain a table mapping the commitment version to a modulus, but this would not allow smart contract to take into account future upgrades to a modulus that is not known yet. By allowing access to the modulus inside the EVM, the smart contract can be built so that it can use future commitments and proofs, without ever needing an upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;In the interest of not adding another precompile, we return the modulus and the polynomial degree directly from the point evaluation precompile. It can then be used by the caller. It is also &quot;free&quot; in that the caller can just ignore this part of the return value without incurring an extra cost -- systems that remain upgradable for the foreseeable future will likely use this route for now.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;base-fee-per-blob-gas-update-rule&quot;&gt;Base fee per blob gas update rule&lt;&#x2F;h3&gt;
&lt;p&gt;The base fee per blob gas update rule is intended to approximate the formula &lt;code&gt;base_fee_per_blob_gas = MIN_BASE_FEE_PER_BLOB_GAS * e**(excess_blob_gas &#x2F; BLOB_BASE_FEE_UPDATE_FRACTION)&lt;&#x2F;code&gt;,
where &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; is the total &quot;extra&quot; amount of blob gas that the chain has consumed relative to the &quot;targeted&quot; number (&lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; per block).
Like EIP-1559, it&#x27;s a self-correcting formula: as the excess goes higher, the &lt;code&gt;base_fee_per_blob_gas&lt;&#x2F;code&gt; increases exponentially, reducing usage and eventually forcing the excess back down.&lt;&#x2F;p&gt;
&lt;p&gt;The block-by-block behavior is roughly as follows.
If block &lt;code&gt;N&lt;&#x2F;code&gt; consumes &lt;code&gt;X&lt;&#x2F;code&gt; blob gas, then in block &lt;code&gt;N+1&lt;&#x2F;code&gt; &lt;code&gt;excess_blob_gas&lt;&#x2F;code&gt; increases by &lt;code&gt;X - TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt;,
and so the &lt;code&gt;base_fee_per_blob_gas&lt;&#x2F;code&gt; of block &lt;code&gt;N+1&lt;&#x2F;code&gt; increases by a factor of &lt;code&gt;e**((X - TARGET_BLOB_GAS_PER_BLOCK) &#x2F; BLOB_BASE_FEE_UPDATE_FRACTION)&lt;&#x2F;code&gt;.
Hence, it has a similar effect to the existing EIP-1559, but is more &quot;stable&quot; in the sense that it responds in the same way to the same total usage regardless of how it&#x27;s distributed.&lt;&#x2F;p&gt;
&lt;p&gt;The parameter &lt;code&gt;BLOB_BASE_FEE_UPDATE_FRACTION&lt;&#x2F;code&gt; controls the maximum rate of change of the base fee per blob gas. It is chosen to target a maximum change rate of &lt;code&gt;e**(TARGET_BLOB_GAS_PER_BLOCK &#x2F; BLOB_BASE_FEE_UPDATE_FRACTION) ≈ 1.125&lt;&#x2F;code&gt; per block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;throughput&quot;&gt;Throughput&lt;&#x2F;h3&gt;
&lt;p&gt;The values for &lt;code&gt;TARGET_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; and &lt;code&gt;MAX_BLOB_GAS_PER_BLOCK&lt;&#x2F;code&gt; are chosen to correspond to a target of 3 blobs (0.375 MB) and maximum of 6 blobs (0.75 MB) per block. These small initial limits are intended to minimize the strain on the network created by this EIP and are expected to be increased in future upgrades as the network demonstrates reliability under larger blocks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;blob-non-accessibility&quot;&gt;Blob non-accessibility&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP introduces a transaction type that has a distinct mempool version and execution-payload version,
with only one-way convertibility between the two. The blobs are in the network representation and not in the consensus representation;
instead, they are coupled with the beacon block. This means that there is now a part of a transaction that will not be accessible from the web3 API.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mempool-issues&quot;&gt;Mempool issues&lt;&#x2F;h3&gt;
&lt;p&gt;Blob transactions have a large data size at the mempool layer, which poses a mempool DoS risk,
though not an unprecedented one as this also applies to transactions with large amounts of calldata.&lt;&#x2F;p&gt;
&lt;p&gt;By only broadcasting announcements for blob transactions, receiving nodes will have control over which and how many transactions to receive,
allowing them to throttle throughput to an acceptable level.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;5793&#x2F;&quot;&gt;EIP-5793&lt;&#x2F;a&gt; will give further fine-grained control to nodes by extending the &lt;code&gt;NewPooledTransactionHashes&lt;&#x2F;code&gt; announcement messages to include the transaction type and size.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, we recommend including a 1.1x base fee per blob gas bump requirement to the mempool transaction replacement rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Execution layer test cases for this EIP can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;tree&#x2F;1983444bbe1a471886ef7c0e82253ffe2a4053e1&#x2F;tests&#x2F;cancun&#x2F;eip4844_blobs&quot;&gt;&lt;code&gt;eip4844_blobs&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; of the &lt;code&gt;ethereum&#x2F;execution-spec-tests&lt;&#x2F;code&gt; repository. Consensus layer test cases can be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;tree&#x2F;2297c09b7e457a13f7b2261a28cb45777be82f83&#x2F;tests&#x2F;core&#x2F;pyspec&#x2F;eth2spec&#x2F;test&#x2F;deneb&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP increases the bandwidth requirements per beacon block by a maximum of ~0.75 MB.
This is 40% larger than the theoretical maximum size of a block today (30M gas &#x2F; 16 gas per calldata byte = 1.875M bytes), and so it will not greatly increase worst-case bandwidth.
Post-merge, block times are static rather than an unpredictable Poisson distribution, giving a guaranteed period of time for large blocks to propagate.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;sustained&lt;&#x2F;em&gt; load of this EIP is much lower than alternatives that reduce calldata costs, even if the calldata is limited,
because there is no expectation that the blobs need to be stored for as long as an execution payload.
This makes it possible to implement a policy that these blobs must be kept for at least a certain period. The specific value chosen is &lt;code&gt;MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS&lt;&#x2F;code&gt; epochs, which is around 18 days,
a much shorter delay compared to proposed (but yet to be implemented) one-year rotation times for execution payload history.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Hierarchical Domains</title>
        <published>2022-02-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4834/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-4834-hierarchical-domains-standard/8388" />
        

        <id>https://wg-eips.ritovision.com/4834/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4834"
            label="ERC-4834" />
        

        
        

        
        <summary type="html">Extremely generic name resolution</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4834/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This is a standard for generic name resolution with arbitrarily complex access control and resolution. It permits a contract that implements this EIP (referred to as a &quot;domain&quot; hereafter) to be addressable with a more human-friendly name, with a similar purpose to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;ERC-137&lt;&#x2F;a&gt; (also known as &quot;ENS&quot;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The advantage of this EIP over existing standards is that it provides a minimal interface that supports name resolution, adds standardized access control, and has a simple architecture. ENS, although useful, has a comparatively complex architecture and does not have standard access control.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, all domains (including subdomains, TLDs, and even the root itself) are actually implemented as domains, meaning that name resolution is a simple iterative algorithm, not unlike DNS itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-interface&quot;&gt;Contract Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Query if a domain has a subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to query, in right to left order&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     `true` if the domain has a subdomain with the given name, `false` otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Fetch the subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This should revert if `hasDomain(name)` is `false`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to fetch, in right to left order&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; subdomain with the given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;name-resolution&quot;&gt;Name Resolution&lt;&#x2F;h3&gt;
&lt;p&gt;To resolve a name (like &lt;code&gt;&quot;a.b.c&quot;&lt;&#x2F;code&gt;), split it by the delimiter (resulting in something like &lt;code&gt;[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]&lt;&#x2F;code&gt;). Set &lt;code&gt;domain&lt;&#x2F;code&gt; initially to the root domain, and &lt;code&gt;path&lt;&#x2F;code&gt; to be an empty list.&lt;&#x2F;p&gt;
&lt;p&gt;Pop off the last element of the array (&lt;code&gt;&quot;c&quot;&lt;&#x2F;code&gt;) and add it to the path, then call &lt;code&gt;domain.hasDomain(path)&lt;&#x2F;code&gt;. If it&#x27;s &lt;code&gt;false&lt;&#x2F;code&gt;, then the domain resolution fails. Otherwise, set the domain to &lt;code&gt;domain.getDomain(path)&lt;&#x2F;code&gt;. Repeat until the list of split segments is empty.&lt;&#x2F;p&gt;
&lt;p&gt;There is no limit to the amount of nesting that is possible. For example, &lt;code&gt;0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z&lt;&#x2F;code&gt; would be valid if the root contains &lt;code&gt;z&lt;&#x2F;code&gt;, and &lt;code&gt;z&lt;&#x2F;code&gt; contains &lt;code&gt;y&lt;&#x2F;code&gt;, and so on.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a solidity function that resolves a name:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resolve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; splitName&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; root&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;    IDomain current &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; path &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; splitName&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Append to back of list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        path&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;splitName&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Require that the current domain has a domain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;current&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;hasDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Name resolution failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Resolve subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        current &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&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;h3 id=&quot;optional-extension-registerable&quot;&gt;Optional Extension: Registerable&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomainRegisterable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F; Events&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Must be emitted when a new subdomain is created (e.g. through `createDomain`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; msg.sender for createDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; name for createDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; subdomain in createDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SubdomainCreate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Must be emitted when the resolved address for a domain is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (e.g. with `setDomain`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; msg.sender for setDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; name for setDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; subdomain in setDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      oldSubdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the old subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SubdomainUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldSubdomain&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Must be emitted when a domain is unmapped (e.g. with `deleteDomain`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; msg.sender for deleteDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; name for deleteDomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the old subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SubdomainDelete&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F; CRUD&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Create a subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This should revert if `canCreateDomain(msg.sender, name, pointer)` is `false` or if the domain exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain name to be created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Update a subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This should revert if `canSetDomain(msg.sender, name, pointer)` is `false` of if the domain doesn&amp;#39;t exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain name to be updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Delete the subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This should revert if the domain doesn&amp;#39;t exist or if `canDeleteDomain(msg.sender, name)` is `false`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; deleteDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F; Parent Domain Access Control&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get if an account can create a subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This must return `false` if `hasDomain(name)` is `true`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      updater&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that may or may not be able to create&#x2F;update a subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain name that would be created&#x2F;updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain that would be set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an account can update or create the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canCreateDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; updater&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get if an account can update or create a subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This must return `false` if `hasDomain(name)` is `false`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             If `getDomain(name)` is also a domain implementing the subdomain access control extension, this should return `false` if `getDomain(name).canMoveSubdomain(msg.sender, this, subdomain)` is `false`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      updater&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that may or may not be able to create&#x2F;update a subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain name that would be created&#x2F;updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      subdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain that would be set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an account can update or create the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canSetDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; updater&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subdomain&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get if an account can delete the subdomain with a given name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        This must return `false` if `hasDomain(name)` is `false`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             If `getDomain(name)` is a domain implementing the subdomain access control extension, this should return `false` if `getDomain(name).canDeleteSubdomain(msg.sender, this, subdomain)` is `false`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      updater&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that may or may not be able to delete a subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an account can delete the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canDeleteDomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; updater&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-extension-enumerable&quot;&gt;Optional Extension: Enumerable&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomainEnumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Query all subdomains. Must revert if the number of domains is unknown or infinite.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; subdomain with the given index.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; subdomainByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get the total number of subdomains. Must revert if the number of domains is unknown or infinite.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; total number of subdomains.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSubdomains&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;optional-extension-access-control&quot;&gt;Optional Extension: Access Control&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomainAccessControl&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get if an account can move the subdomain away from the current domain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        May be called by `canSetDomain` of the parent domain - implement access control here!!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      updater&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that may be moving the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The parent domain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      newSubdomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The domain that will be set next&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an account can update the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canMoveSubdomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; updater&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newSubdomain&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Get if an account can unset this domain as a subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        May be called by `canDeleteDomain` of the parent domain - implement access control here!!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      updater&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The account that may or may not be able to delete a subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The subdomain to delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;      parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The parent domain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;     Whether&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; an account can delete the subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canDeleteSubdomain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; updater&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IDomain&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP&#x27;s goal, as mentioned in the abstract, is to have a simple interface for resolving names. Here are a few design decisions and why they were made:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Name resolution algorithm
&lt;ul&gt;
&lt;li&gt;Unlike ENS&#x27;s resolution algorithm, this EIP&#x27;s name resolution is fully under the control of the contracts along the resolution path.&lt;&#x2F;li&gt;
&lt;li&gt;This behavior is more intuitive to users.&lt;&#x2F;li&gt;
&lt;li&gt;This behavior allows for greater flexibility - e.g. a contract that changes what it resolves to based on the time of day.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Parent domain access control
&lt;ul&gt;
&lt;li&gt;A simple &quot;ownable&quot; interface was not used because this specification was designed to be as generic as possible. If an ownable implementation is desired, it can be implemented.&lt;&#x2F;li&gt;
&lt;li&gt;This also gives parent domains the ability to call subdomains&#x27; access control methods so that subdomains, too, can choose whatever access control mechanism they desire&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Subdomain access control
&lt;ul&gt;
&lt;li&gt;These methods are included so that subdomains aren&#x27;t always limited to their parent domain&#x27;s access control&lt;&#x2F;li&gt;
&lt;li&gt;The root domain can be controlled by a DAO with a non-transferable token with equal shares, a TLD can be controlled by a DAO with a token representing stake, a domain of that TLD can be controlled by a single owner, a subdomain of that domain can be controlled by a single owner linked to an NFT, and so on.&lt;&#x2F;li&gt;
&lt;li&gt;Subdomain access control functions are suggestions: an ownable domain might implement an owner override, so that perhaps subdomains might be recovered if the keys are lost.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is general enough to support ENS, but ENS is not general enough to support this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;malicious-canmovesubdomain-black-hole&quot;&gt;Malicious canMoveSubdomain (Black Hole)&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;description-malicious-canmovesubdomain&quot;&gt;Description: Malicious &lt;code&gt;canMoveSubdomain&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Moving a subdomain using &lt;code&gt;setDomain&lt;&#x2F;code&gt; is a potentially dangerous operation.&lt;&#x2F;p&gt;
&lt;p&gt;Depending on the parent domain&#x27;s implementation, if a malicious new subdomain unexpectedly returns &lt;code&gt;false&lt;&#x2F;code&gt; on &lt;code&gt;canMoveSubdomain&lt;&#x2F;code&gt;, that subdomain can effectively lock the ownership of the domain.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, it might return &lt;code&gt;true&lt;&#x2F;code&gt; when it isn&#x27;t expected (i.e. a backdoor), allowing the contract owner to take over the domain.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mitigation-malicious-canmovesubdomain&quot;&gt;Mitigation: Malicious &lt;code&gt;canMoveSubdomain&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Clients should help by warning if &lt;code&gt;canMoveSubdomain&lt;&#x2F;code&gt; or &lt;code&gt;canDeleteSubdomain&lt;&#x2F;code&gt; for the new subdomain changes to &lt;code&gt;false&lt;&#x2F;code&gt;. It is important to note, however, that since these are functions, it is possible for the value to change depending on whether or not it has already been linked. It is also still possible for it to unexpectedly return true. It is therefore recommended to &lt;strong&gt;always&lt;&#x2F;strong&gt; audit the new subdomain&#x27;s source code before calling &lt;code&gt;setDomain&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parent-domain-resolution&quot;&gt;Parent Domain Resolution&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;description-parent-domain-resolution&quot;&gt;Description: Parent Domain Resolution&lt;&#x2F;h4&gt;
&lt;p&gt;Parent domains have full control of name resolution for their subdomains. If a particular domain is linked to &lt;code&gt;a.b.c&lt;&#x2F;code&gt;, then &lt;code&gt;b.c&lt;&#x2F;code&gt; can, depending on its code, set &lt;code&gt;a.b.c&lt;&#x2F;code&gt; to any domain, and &lt;code&gt;c&lt;&#x2F;code&gt; can set &lt;code&gt;b.c&lt;&#x2F;code&gt; itself to any domain.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mitigation-parent-domain-resolution&quot;&gt;Mitigation: Parent Domain Resolution&lt;&#x2F;h4&gt;
&lt;p&gt;Before acquiring a domain that has been pre-linked, it is recommended to always have the contract &lt;strong&gt;and&lt;&#x2F;strong&gt; all the parents up to the root audited.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Web3 URL to EVM Call Message Translation</title>
        <published>2022-02-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Qi Zhou</name><uri>https://github.com/qizhou</uri>
	</author>
	
	<author>
		<name>Chao Pi</name><uri>https://github.com/pichaoqkc</uri>
	</author>
	
	<author>
		<name>Sam Wilson</name><uri>https://github.com/SamWilsn</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4804/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4804-web3-url-to-evm-call-message-translation/8300" />
        

        <id>https://wg-eips.ritovision.com/4804/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:4804"
            label="ERC-4804" />
        

        
        

        
        <summary type="html">A translation of an HTTP-style Web3 URL to an EVM call message</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4804/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard translates an RFC 2396 URI like &lt;code&gt;web3:&#x2F;&#x2F;uniswap.eth&#x2F;&lt;&#x2F;code&gt; to an EVM message such as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EVMMessage {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   To: 0xaabbccddee.... &#x2F;&#x2F; where uniswap.eth&amp;#39;s address registered at ENS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Calldata: 0x&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;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, reading data from Web3 generally relies on a translation done by a Web2 proxy to Web3 blockchain. The translation is mostly done by the proxies such as dApp websites&#x2F;node service provider&#x2F;etherscan, which are out of the control of users. The standard here aims to provide a simple way for Web2 users to directly access the content of Web3, especially on-chain Web contents such as SVG&#x2F;HTML.  Moreover, this standard enables interoperability with other standards already compatible with URIs, like SVG&#x2F;HTML.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;This specification only defines read-only (i.e. Solidity&#x27;s &lt;code&gt;view&lt;&#x2F;code&gt; functions) semantics. State modifying functions may be defined as a future extension.&lt;&#x2F;p&gt;
&lt;p&gt;A Web3 URL is in the following form&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3URL = web3Schema [userinfo &amp;quot;@&amp;quot;] contractName [&amp;quot;:&amp;quot; chainid] path [&amp;quot;?&amp;quot; query]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3Schema = [ &amp;quot;ethereum-web3:&#x2F;&#x2F;&amp;quot; | &amp;quot;eth-web3:&#x2F;&#x2F;&amp;quot; | &amp;quot;web3:&#x2F;&#x2F;&amp;quot; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contractName = address | [name &amp;quot;.&amp;quot; [ subDomain0 &amp;quot;.&amp;quot; ... ]] nsProviderSuffix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path = [&amp;quot;&#x2F;&amp;quot; method [&amp;quot;&#x2F;&amp;quot; argument_0 [&amp;quot;&#x2F;&amp;quot; argument_1 ... ]]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;argument = [type &amp;quot;!&amp;quot;] value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;query = &amp;quot;attribute_1=value_1 [ &amp;quot;&amp;amp;&amp;quot; attribute_2=value_2 ... ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;attribute = &amp;quot;returns&amp;quot; | &amp;quot;returnTypes&amp;quot; | other_attribute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;web3Schema&lt;&#x2F;strong&gt; indicates the schema of the URL, which is &lt;code&gt;web3:&#x2F;&#x2F;&lt;&#x2F;code&gt; or &lt;code&gt;w3:&#x2F;&#x2F;&lt;&#x2F;code&gt; for short.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;userinfo&lt;&#x2F;strong&gt; indicates which user is calling the EVM, i.e., &quot;From&quot; field in EVM call message. If not specified, the protocol will use 0x0 as the sender address.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;contractName&lt;&#x2F;strong&gt; indicates the contract to be called, i.e., &quot;To&quot; field in the EVM call message. If the &lt;strong&gt;contractName&lt;&#x2F;strong&gt; is an &lt;strong&gt;address&lt;&#x2F;strong&gt;, i.e., 0x + 20-byte-data hex, then &quot;To&quot; will be the address. Otherwise, the name is from a name service. In the second case, &lt;strong&gt;nsProviderSuffix&lt;&#x2F;strong&gt; will be the suffix from name service providers such as &quot;eth&quot;, etc. The way to translate the name from a name service to an address will be discussed in later EIPs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;chainid&lt;&#x2F;strong&gt; indicates which chain to resolve &lt;strong&gt;contractName&lt;&#x2F;strong&gt; and call the message. If not specified, the protocol will use the same chain as the name service provider, e.g., 1 for eth. If no name service provider is available, the default chainid is 1.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;query&lt;&#x2F;strong&gt; is an optional component containing a sequence of attribute-value pairs separated by &quot;&amp;amp;&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;resolve-mode&quot;&gt;Resolve Mode&lt;&#x2F;h3&gt;
&lt;p&gt;Once the &quot;To&quot; address and chainid are determined, the protocol will check the resolver mode of contract by calling &quot;resolveMode&quot; method. The protocol currently supports two resolve modes:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;manual-mode&quot;&gt;Manual Mode&lt;&#x2F;h4&gt;
&lt;p&gt;The manual mode will not do any interpretation of &lt;strong&gt;path&lt;&#x2F;strong&gt; and &lt;strong&gt;query&lt;&#x2F;strong&gt;, and put &lt;strong&gt;path&lt;&#x2F;strong&gt; [ &quot;?&quot; &lt;strong&gt;query&lt;&#x2F;strong&gt; ] as the calldata of the message directly.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;auto-mode&quot;&gt;Auto Mode&lt;&#x2F;h4&gt;
&lt;p&gt;The auto mode is the default mode to resolve (also applies when the &quot;resolveMode&quot; method is unavailable in the target contract). In the auto mode, if &lt;strong&gt;path&lt;&#x2F;strong&gt; is empty, then the protocol will call the target contract with empty calldata. Otherwise, the calldata of the EVM message will use standard Solidity contract ABI, where&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;method&lt;&#x2F;strong&gt; is a string of function method be called&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;argument_i&lt;&#x2F;strong&gt; is the ith argument of the method. If &lt;strong&gt;type&lt;&#x2F;strong&gt; is specified, the value will be translated to the corresponding type. The protocol currently supports the basic types such as uint256, bytes32, address, bytes, and string. If &lt;strong&gt;type&lt;&#x2F;strong&gt; is not specified, then the type will be automatically detected using the following rule in a sequential way:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;type&lt;&#x2F;strong&gt;=&quot;uint256&quot;, if &lt;strong&gt;value&lt;&#x2F;strong&gt; is numeric; or&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;type&lt;&#x2F;strong&gt;=&quot;bytes32&quot;, if &lt;strong&gt;value&lt;&#x2F;strong&gt; is in the form of 0x+32-byte-data hex; or&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;type&lt;&#x2F;strong&gt;=&quot;address&quot;, if &lt;strong&gt;value&lt;&#x2F;strong&gt; is in the form of 0x+20-byte-data hex; or&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;type&lt;&#x2F;strong&gt;=&quot;bytes&quot;, if &lt;strong&gt;value&lt;&#x2F;strong&gt; is in the form of 0x followed by any number of bytes besides 20 or 32; or&lt;&#x2F;li&gt;
&lt;li&gt;else &lt;strong&gt;type&lt;&#x2F;strong&gt;=&quot;address&quot; and parse the argument as a domain name in the form of &lt;code&gt;[name &quot;.&quot; [ subDomain0 &quot;.&quot; ... ]] nsProviderSuffix&lt;&#x2F;code&gt;. In this case, the actual value of the argument will be obtained from &lt;strong&gt;nsProviderSuffix&lt;&#x2F;strong&gt;, e.g., eth.  If &lt;strong&gt;nsProviderSuffix&lt;&#x2F;strong&gt; is not supported, an unsupported NS provider error will be returned.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that if &lt;strong&gt;method&lt;&#x2F;strong&gt; does not exist, i.e., &lt;strong&gt;path&lt;&#x2F;strong&gt; is empty or &quot;&#x2F;&quot;, then the contract will be called with empty calldata.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;returns&lt;&#x2F;strong&gt; attribute in &lt;strong&gt;query&lt;&#x2F;strong&gt; tells the format of the returned data. If not specified, the returned message data will be parsed in &quot;(bytes32)&quot; and MIME will be set based on the suffix of the last argument. If &lt;strong&gt;returns&lt;&#x2F;strong&gt; is &quot;()&quot;, the returned data will be parsed in raw bytes in JSON.  Otherwise, the returned message will be parsed in the specified &lt;strong&gt;returns&lt;&#x2F;strong&gt; attribute in JSON.  If multiple &lt;strong&gt;returns&lt;&#x2F;strong&gt; attributes are present, the value of the last &lt;strong&gt;returns&lt;&#x2F;strong&gt; attribute will be applied. Note that &lt;strong&gt;returnTypes&lt;&#x2F;strong&gt; is the alias of &lt;strong&gt;returns&lt;&#x2F;strong&gt;, but it is not recommended to use and is mainly for backward-compatible purpose.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;example-1&quot;&gt;Example 1&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;w3url.eth&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will find the address of &lt;strong&gt;w3url.eth&lt;&#x2F;strong&gt; from ENS in chainid 1 (Mainnet), and then the protocol will call the address with &quot;From&quot; = &quot;0x...&quot; and &quot;Calldata&quot; = &quot;0x2F&quot;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-2&quot;&gt;Example 2&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;cyberbrokers-meta.eth&#x2F;renderBroker&#x2F;9999&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will find the address of &lt;strong&gt;cyberbrokers-meta.eth&lt;&#x2F;strong&gt; from ENS on chainid 1 (Mainnet), and then call the address with &quot;To&quot; = &quot;0x...&quot; and &quot;Calldata&quot; = &quot;0x&quot; + &lt;code&gt;keccak(&quot;view(uint256)&quot;)[0:4] + abi.encode(uint256(9999))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-3&quot;&gt;Example 3&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;vitalikblog.eth:5&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will find the address of &lt;strong&gt;vitalikblog.eth&lt;&#x2F;strong&gt; from ENS on chainid 5 (Goerli), and then call the address with &quot;From&quot; = &quot;0x...&quot; and &quot;Calldata&quot; = &quot;0x2F&quot; with chainid = 5.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-4&quot;&gt;Example 4&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will call the address with &quot;To&quot; = &quot;0x9e081Df45E0D167636DB9C61C7ce719A58d82E3b&quot; and &quot;Calldata&quot; = &quot;0x&quot; with chainid = 42170 (Arbitrum Nova).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-5&quot;&gt;Example 5&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&#x2F;balanceOf&#x2F;vitalik.eth?returns=(uint256)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will find the addresses of &lt;strong&gt;vitalik.eth&lt;&#x2F;strong&gt; from ENS on chainid 1 (Mainnet) and then call the method &quot;balanceOf(address)&quot; of the contract with the &lt;strong&gt;charles.eth&lt;&#x2F;strong&gt;&#x27;s address. The returned data will be parsed as uint256 like &lt;code&gt;[ &quot;10000000000000&quot; ]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-6&quot;&gt;Example 6&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web3:&#x2F;&#x2F;0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&#x2F;balanceOf&#x2F;vitalik.eth?returns=()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The protocol will find the address of &lt;strong&gt;vitalik.eth&lt;&#x2F;strong&gt; from ENS on chainid 1 (Mainnet) and then call the method &quot;balanceOf(address)&quot; of the address. The returned data will be parsed as raw bytes like &lt;code&gt;[&quot;0x000000000000000000000000000000000000000000000000000009184e72a000&quot;]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The purpose of the proposal is to add a decentralized presentation layer for Ethereum.  With the layer, we are able to render any web content (including HTML&#x2F;CSS&#x2F;JPG&#x2F;PNG&#x2F;SVG, etc) on-chain using human-readable URLs, and thus EVM can be served as decentralized Backend.  The design of the standard is based on the following principles:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Human-readable&lt;&#x2F;strong&gt;.  The Web3 URL should be easily recognized by human similar to Web2 URL (&lt;code&gt;http:&#x2F;&#x2F;&lt;&#x2F;code&gt;).  As a result, we support names from name services to replace address for better readability.  In addition, instead of using calldata in hex, we use human-readable method + arguments and translate them to calldata for better readability.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maximum-Compatible with HTTP-URL standard&lt;&#x2F;strong&gt;.  The Web3 URL should be compatible with HTTP-URL standard including relative pathing, query, fragment, etc so that the support of existing HTTP-URL (e.g., by browser) can be easily extended to Web3 URL with minimal modification.  This also means that existing Web2 users can easily migrate to Web3 with minimal extra knowledge of this standard.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Simple&lt;&#x2F;strong&gt;.  Instead of providing explicit types in arguments, we use a &quot;maximum likelihood&quot; principle of auto-detecting the types of the arguments such as address, bytes32, and uint256.  This could greatly minimize the length of URL, while avoiding confusion.  In addition, explicit types are also supported to clear the confusion if necessary.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flexible&lt;&#x2F;strong&gt;.  The contract is able to override the encoding rule so that the contract has fine-control of understanding the actual Web resources that the users want to locate.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;No security considerations were found.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Beacon block root in the EVM</title>
        <published>2022-02-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	<author>
		<name>Ansgar Dietrichs</name><uri>https://github.com/adietrichs</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Martin Holst Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	<author>
		<name>lightclient</name><uri>https://github.com/lightclient</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4788/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4788-beacon-root-in-evm/8281" />
        

        <id>https://wg-eips.ritovision.com/4788/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4788"
            label="EIP-4788" />
        

        
        

        
        <summary type="html">Expose beacon chain roots in the EVM</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4788/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Commit to the hash tree root of each beacon chain block in the corresponding execution payload header.&lt;&#x2F;p&gt;
&lt;p&gt;Store each of these roots in a smart contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Roots of the beacon chain blocks are cryptographic accumulators that allow proofs of arbitrary consensus state.
Exposing these roots inside the EVM allows for trust-minimized access to the consensus layer.
This functionality supports a wide variety of use cases that improve trust assumptions of staking pools,
restaking constructions, smart contract bridges, MEV mitigations and more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;constants&lt;&#x2F;th&gt;&lt;th&gt;value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_TIMESTAMP&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1710338135&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;8191&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;background&quot;&gt;Background&lt;&#x2F;h3&gt;
&lt;p&gt;The high-level idea is that each execution block contains the parent beacon block&#x27;s root. Even in the event of missed slots since the previous block root does not change,
we only need a constant amount of space to represent this &quot;oracle&quot; in each execution block. To improve the usability of this oracle, a small history of block roots
are stored in the contract.&lt;&#x2F;p&gt;
&lt;p&gt;To bound the amount of storage this construction consumes, a ring buffer is used that mirrors a block root accumulator on the consensus layer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-structure-and-validity&quot;&gt;Block structure and validity&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning at the execution timestamp &lt;code&gt;FORK_TIMESTAMP&lt;&#x2F;code&gt;, execution clients &lt;strong&gt;MUST&lt;&#x2F;strong&gt; extend the header schema with an additional field: the &lt;code&gt;parent_beacon_block_root&lt;&#x2F;code&gt;.
This root consumes 32 bytes and is exactly the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;fa09d896484bbe240334fa21ffaa454bafe5842e&#x2F;ssz&#x2F;simple-serialize.md#merkleization&quot;&gt;hash tree root&lt;&#x2F;a&gt; of the parent beacon block for the given execution block.&lt;&#x2F;p&gt;
&lt;p&gt;The resulting RLP encoding of the header is therefore:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp&lt;&#x2F;span&gt;&lt;span&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&gt;    parent_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ommers hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    coinbase&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    txs_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    receipts_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    logs_bloom&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; difficulty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    number&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gas_used&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    timestamp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    extradata&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prev_randao&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0000000000000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    withdrawals_root&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blob_gas_used&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    excess_blob_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    parent_beacon_block_root&lt;&#x2F;span&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;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Validity of the parent beacon block root is guaranteed from the consensus layer, much like how withdrawals are handled.&lt;&#x2F;p&gt;
&lt;p&gt;When verifying a block, execution clients &lt;strong&gt;MUST&lt;&#x2F;strong&gt; ensure the root value in the block header matches the one provided by the consensus client.&lt;&#x2F;p&gt;
&lt;p&gt;For a genesis block with no existing parent beacon block root the 32 zero bytes are used as a root placeholder.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;beacon-roots-contract&quot;&gt;Beacon roots contract&lt;&#x2F;h4&gt;
&lt;p&gt;The beacon roots contract has two operations: &lt;code&gt;get&lt;&#x2F;code&gt; and &lt;code&gt;set&lt;&#x2F;code&gt;. The input itself is not used to determine which function to execute, for that the result of &lt;code&gt;caller&lt;&#x2F;code&gt; is used. If &lt;code&gt;caller&lt;&#x2F;code&gt; is equal to &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; then the operation to perform is &lt;code&gt;set&lt;&#x2F;code&gt;. Otherwise, &lt;code&gt;get&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;get&quot;&gt;&lt;code&gt;get&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;Callers provide the &lt;code&gt;timestamp&lt;&#x2F;code&gt; they are querying encoded as 32 bytes in big-endian format.&lt;&#x2F;li&gt;
&lt;li&gt;If the input is not exactly 32 bytes, the contract must revert.&lt;&#x2F;li&gt;
&lt;li&gt;If the input is equal to 0, the contract must revert.&lt;&#x2F;li&gt;
&lt;li&gt;Given &lt;code&gt;timestamp&lt;&#x2F;code&gt;, the contract computes the storage index in which the timestamp is stored by computing the modulo &lt;code&gt;timestamp % HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt; and reads the value.&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;timestamp&lt;&#x2F;code&gt; does not match, the contract must revert.&lt;&#x2F;li&gt;
&lt;li&gt;Finally, the beacon root associated with the timestamp is returned to the user. It is stored at &lt;code&gt;timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;set&quot;&gt;&lt;code&gt;set&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;Caller provides the parent beacon block root as calldata to the contract.&lt;&#x2F;li&gt;
&lt;li&gt;Set the storage value at &lt;code&gt;header.timestamp % HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt; to be &lt;code&gt;header.timestamp&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Set the storage value at &lt;code&gt;header.timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt; to be &lt;code&gt;calldata[0:32]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;pseudocode&quot;&gt;Pseudocode&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; SYSTEM_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 class=&quot;z-support&quot;&gt;    set&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;    get&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; to_uint256_be&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    timestamp_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to_uint256_be&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; HISTORY_BUFFER_LENGTH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; storage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;timestamp_idx&lt;&#x2F;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;        evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    root_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; timestamp_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; HISTORY_BUFFER_LENGTH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; storage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;root_idx&lt;&#x2F;span&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&gt;    evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;root&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;    timestamp_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to_uint256_be&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; HISTORY_BUFFER_LENGTH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    root_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; timestamp_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; HISTORY_BUFFER_LENGTH&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;    storage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;timestamp_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    storage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;root_idx&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calldata&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;bytecode&quot;&gt;Bytecode&lt;&#x2F;h5&gt;
&lt;p&gt;The exact contract bytecode is shared below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push20 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x4d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iszero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x49&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push3 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x001fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x3c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&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;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push3 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x001fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&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;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push3 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x001fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push3 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x001fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;add&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;deployment&quot;&gt;Deployment&lt;&#x2F;h4&gt;
&lt;p&gt;The beacon roots contract is deployed like any other smart contract. A special synthetic address is generated
by working backwards from the desired deployment transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3d090&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe8d4a51000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxPriorityFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x539&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b9b6eb1f0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdf52c2d3bbe38820fff7b5eaab3db1b91f8e1412b56497d88388fb5d4ea1fde0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;Note, the input in the transaction has a simple constructor prefixing the desired runtime code.&lt;&#x2F;p&gt;
&lt;p&gt;The sender of the transaction can be calculated as &lt;code&gt;0x0B799C86a49DEeb90402691F1041aa3AF2d3C875&lt;&#x2F;code&gt;. The address of the first contract deployed from the account is &lt;code&gt;rlp([sender, 0])&lt;&#x2F;code&gt; which equals &lt;code&gt;0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02&lt;&#x2F;code&gt;. This is how &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt; is determined. Although this style of contract creation is not tied to any specific initcode like create2 is, the synthetic address is cryptographically bound to the input data of the transaction (e.g. the initcode).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-processing&quot;&gt;Block processing&lt;&#x2F;h3&gt;
&lt;p&gt;At the start of processing any execution block where &lt;code&gt;block.timestamp &amp;gt;= FORK_TIMESTAMP&lt;&#x2F;code&gt; (i.e. before processing any transactions), call &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt; as &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; with the 32-byte input of &lt;code&gt;header.parent_beacon_block_root&lt;&#x2F;code&gt;, a gas limit of &lt;code&gt;30_000_000&lt;&#x2F;code&gt;, and &lt;code&gt;0&lt;&#x2F;code&gt; value. This will trigger the &lt;code&gt;set()&lt;&#x2F;code&gt; routine of the beacon roots contract. This is a system operation and therefore:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the call must execute to completion&lt;&#x2F;li&gt;
&lt;li&gt;the call does not count against the block&#x27;s gas limit&lt;&#x2F;li&gt;
&lt;li&gt;the call does not follow the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt; burn semantics - no value should be transferred as part of the call&lt;&#x2F;li&gt;
&lt;li&gt;if no code exists at &lt;code&gt;BEACON_ROOTS_ADDRESS&lt;&#x2F;code&gt;, the call must fail silently&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Clients may decide to omit an explicit EVM call and directly set the storage values. Note: While this is a valid optimization for Ethereum mainnet, it could be problematic on non-mainnet situations in case a different contract is used.&lt;&#x2F;p&gt;
&lt;p&gt;If this EIP is active in a genesis block, the genesis header&#x27;s &lt;code&gt;parent_beacon_block_root&lt;&#x2F;code&gt; must be &lt;code&gt;0x0&lt;&#x2F;code&gt; and no system transaction may occur.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-not-repurpose-blockhash&quot;&gt;Why not repurpose &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt;?&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; opcode could be repurposed to provide the beacon root instead of some execution block hash.
To minimize code change, avoid breaking changes to smart contracts, and simplify deployment to mainnet, this EIP suggests leaving &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; alone and adding new
functionality with the desired semantics.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;beacon-block-root-instead-of-state-root&quot;&gt;Beacon block root instead of state root&lt;&#x2F;h3&gt;
&lt;p&gt;Block roots are preferred over state roots so there is a constant amount of work to do with each new execution block. Otherwise, skipped slots would require
a linear amount of work with each new payload. While skipped slots are quite rare on mainnet, it is best to not add additional load under what would already
be nonfavorable conditions.&lt;&#x2F;p&gt;
&lt;p&gt;Use of block root over state root does mean proofs will require a few additional nodes but this cost is negligible (and could be amortized across all consumers,
e.g. with a singleton state root contract that caches the proof per slot).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-two-ring-buffers&quot;&gt;Why two ring buffers?&lt;&#x2F;h3&gt;
&lt;p&gt;The first ring buffer only tracks &lt;code&gt;HISTORY_BUFFER_LENGTH&lt;&#x2F;code&gt; worth of roots and so for all possible timestamp values would consume a constant amount of storage.
However, this design opens the contract to an attack where a skipped slot that has the same value modulo the ring buffer length would return an old root value,
rather than the most recent one.&lt;&#x2F;p&gt;
&lt;p&gt;To nullify this attack while retaining a fixed memory footprint, this EIP keeps track of the pair of data &lt;code&gt;(parent_beacon_block_root, timestamp)&lt;&#x2F;code&gt; for each index into the
ring buffer and verifies the timestamp matches the one originally used to write the root data when being read. Given the fixed size of storage slots (only 32 bytes), the requirement
to store a pair of values necessitates two ring buffers, rather than just one.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;size-of-ring-buffers&quot;&gt;Size of ring buffers&lt;&#x2F;h3&gt;
&lt;p&gt;The ring buffer data structures are sized to hold 8191 roots from the consensus layer. Using a prime number as the ring buffer size ensures that no value is overwritten until the entire ring buffer has been saturated and thereafter, each value will be updated once per iteration. This also means that even if the slot times were to change, we would continue to use at most 8191 storage slots.&lt;&#x2F;p&gt;
&lt;p&gt;Given the current mainnet values, 8191 roots provides about a day of coverage. This gives users plenty of time to make a transaction with a verification against a specific root and get the transaction included on-chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;N&#x2F;A&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;N&#x2F;A&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;N&#x2F;A&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Consensus Layer Withdrawal Protection</title>
        <published>2022-01-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Benjamin Chodroff</name><uri>https://github.com/benjaminchodroff</uri>
	</author>
	
	<author>
		<name>Jim McDonald</name><uri>https://github.com/mcdee</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4736/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/consensus-layer-withdrawal-protection/8161" />
        

        <id>https://wg-eips.ritovision.com/4736/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:4736"
            label="EIP-4736" />
        

        
        

        
        <summary type="html">Additional security for BLSToExecutionChange operation when a consensus layer mnemonic may be compromised, without changing consensus</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4736/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;If a consensus layer mnemonic phrase is compromised, it is impossible for the consensus layer network to differentiate the legitimate holder of the key from an illegitimate holder. However, there are signals that can be considered in a wider sense without changing core Ethereum consensus. This proposal outlines ways in which on chain evidence such as the execution layer deposit address and list of signed messages could create a social consensus that would significantly favor but not guarantee legitimate mnemonic holders would win a race condition against an attacker.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The consensus layer &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; message is secure for a single user who has certainty their keys and mnemonic have not been compromised. However, as validator withdrawals on the consensus layer are not possible until the Capella hard fork, no user can have absolute certainty that their keys are not compromised until the &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; is on chain, and by then too late to change. All legitimate mnemonic phrase holders were originally in control of the execution layer deposit address. Beacon node clients and node operators may optionally load a list of verifiable &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; messages to broadcasts that may create a social consensus for legitimate holders to successfully win a race condition against an attacker. If attackers compromise a significant number of consensus layer nodes, it would pose risks to the entire Ethereum community.&lt;&#x2F;p&gt;
&lt;p&gt;Setting a withdrawal address to an execution layer address was not supported by the eth2.0-deposit-cli until v1.1.1 on March 23, 2021, leaving early adopters wishing they could force set their execution layer address to a deposit address earlier. Forcing this change is not something that can be enforced in-protocol, partly due to lack of information on the beacon chain about the execution layer deposit address and partly due to the fact that this was never listed as a requirement. It is also possible that the execution layer deposit address is no longer under the control of the legitimate holder of the withdrawal private key.&lt;&#x2F;p&gt;
&lt;p&gt;However, it is possible for individual nodes to locally restrict the changes they wish to include in blocks they propose, and which they propagate around the network, in a way that does not change consensus. It is also possible for client nodes to help broadcast signed &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; requests to ensure as many nodes witness this message as soon as possible in a fair manner. Further, such &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; signed messages can be preloaded into clients in advance to further help nodes filter attacking requests.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal provides purely optional additional protection. It aims to request nodes set a priority on withdrawal credential claims that favour a verifiable execution layer deposit address in the event of two conflicting &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; messages. It also establishes a list of &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; signed messages to help broadcast &quot;as soon as possible&quot; when the network supports it, and encourage client teams to help use these lists to honour filter and prioritize accepting requests by REST and transmitting them via P2P. This will not change consensus, but may help prevent propagating an attack where a withdrawal key has been knowingly or unknowingly compromised.&lt;&#x2F;p&gt;
&lt;p&gt;It is critical to understand that this proposal is not a consensus change. Nothing in this proposal restricts the validity of withdrawal credential operations within the protocol. It is a voluntary change by client teams to build this functionality in to their beacon nodes, and a voluntary change by node operators to accept any or all of the restrictions and broadcasting capabilities suggested by end users.&lt;&#x2F;p&gt;
&lt;p&gt;Because of the above, even if fully implemented, it will be down to chance as to which validators propose blocks, and which voluntary restrictions those validators’ beacon nodes are running. Node operators can do what they will to help the community prevent attacks on any compromised consensus layer keys, but there are no guarantees of success this will prevent a successful attack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The Consensus Layer &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; operation has the following fields:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Validator index&lt;&#x2F;li&gt;
&lt;li&gt;Current withdrawal BLS public key&lt;&#x2F;li&gt;
&lt;li&gt;Proposed execution layer withdrawal address&lt;&#x2F;li&gt;
&lt;li&gt;Signature by withdrawal private key over the prior fields&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This proposal describes OPTIONAL and RECOMMENDED mechanisms which a client beacon node MAY implement, and end users are RECOMMENDED to use in their beacon node operation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blstoexecutionchange-broadcast-file&quot;&gt;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast File&lt;&#x2F;h3&gt;
&lt;p&gt;Beacon node clients MAY support an OPTIONAL file of lines specifying &quot;validator index&quot; , &quot;current withdrawal BLS public key&quot; , &quot;proposed execution layer withdrawal address&quot;, and &quot;signature&quot; which, if implemented and if provided, SHALL instruct nodes to automatically submit a one-time &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; broadcast message for each valid signature at the Capella hard fork. This file SHALL give all node operators an OPTIONAL opportunity to ensure any valid &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; messages are broadcast, heard, and shared by nodes at the Capella hard fork. This OPTIONAL file SHALL also instruct nodes to perpetually prefer accepting and repeating signatures matching the signature in the file, and SHALL reject accepting or rebroadcasting messages which do not match a signature for a given withdrawal credential.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blstoexecutionchange-handling&quot;&gt;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Handling&lt;&#x2F;h3&gt;
&lt;p&gt;Beacon node clients are RECOMMENDED to allow accepting &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; file of verifiable signatures, and then MAY fallback to accept a &quot;first request&quot; via P2P. All of this proposal is OPTIONAL for beacon nodes to implement or use, but all client teams are RECOMMENDED to allow a &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast File&quot; to be loaded locally before the Capella hard fork. This OPTIONAL protection will allow a user to attempt to set a withdrawal address message as soon as the network supports it without any change to consensus.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is intended to protect legitimate validator mnemonic holders where it was knowingly or unknowingly compromised. As there is no safe way to transfer ownership of a validator without exiting, it can safely be assumed that all validator holders intend to set to a withdrawal address they specify. Using the deposit address in the execution layer to determine the legitimate holder is not possible to consider in consensus as it may be far back in history and place an overwhelming burden to maintain such a list. As such, this proposal outlines optional mechanism which protect legitimate original mnemonic holders and does so in a way that does not place any mandatory burden on client node software or operators.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As there is no existing &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; operation prior to Capella, there is no documented backwards compatibility. As all of the proposal is OPTIONAL in both implementation and operation, it is expected that client beacon nodes that do not implement this functionality would still remain fully backwards compatible with any or all clients that do implement part or all of the functionality described in this proposal. Additionally, while users are RECOMMENDED to enable these OPTIONAL features, if they decide to either disable or ignore some or all of the features, or even purposefully load content contrary to the intended purpose, the beacon node client will continue to execute fully compatible with the rest of the network as none of the proposal will change core Ethereum consensus.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;blstoexecutionchange-broadcast-file-1&quot;&gt;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast File&lt;&#x2F;h3&gt;
&lt;p&gt;A &quot;change-operations.json&quot; file intended to be preloaded with all consensus layer withdrawal credential signatures and verifiable execution layer deposit addresses. This file may be generated by a script and able to be independently verified by community members using the consensus layer node, and intended to be included by all clients, enabled by default. Client nodes are encouraged to enable packaging this independently verifiable list with the client software, and enable it by default to help further protect the community from unsuspected attacks.&lt;&#x2F;p&gt;
&lt;p&gt;The change-operations.json format is the &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; File - Claim&quot; combined into a single JSON array.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blstoexecutionchange-broadcast-file-claim&quot;&gt;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast File - Claim&lt;&#x2F;h3&gt;
&lt;p&gt;A community collected and independently verifiable list of &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcasts&quot; containing verifiable claims will be collected. Node operators may verify these claims independently and are suggested to load claims in compatible beacon node clients.&lt;&#x2F;p&gt;
&lt;p&gt;To make a verifiable claim, users MAY upload a claim to any public repository in a text file &quot;[chain]&#x2F;validatorIndex.json&quot; such as &quot;mainnet&#x2F;123456.json&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;123456.json:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[{&amp;quot;message&amp;quot;:{&amp;quot;validator_index&amp;quot;:&amp;quot;123456&amp;quot;,&amp;quot;from_bls_pubkey&amp;quot;:&amp;quot;0x977cc21a067003e848eb3924bcf41bd0e820fbbce026a0ff8e9c3b6b92f1fea968ca2e73b55b3908507b4df89eae6bfb&amp;quot;,&amp;quot;to_execution_address&amp;quot;:&amp;quot;0x08f2e9Ce74d5e787428d261E01b437dC579a5164&amp;quot;},&amp;quot;signature&amp;quot;:&amp;quot;0x872935e0724b31b2f0209ac408b673e6fe2f35b640971eb2e3b429a8d46be007c005431ef46e9eb11a3937f920cafe610c797820ca088543c6baa0b33797f0a38f6db3ac68ffc4fd03290e35ffa085f0bfd56b571d7b2f13c03f7b6ce141c283&amp;quot;}]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;claim-acceptance&quot;&gt;Claim Acceptance&lt;&#x2F;h4&gt;
&lt;p&gt;In order for a submission to be merged into public repository, the submission must have:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Valid filename in the format validatorIndex.json&lt;&#x2F;li&gt;
&lt;li&gt;Valid validator index which is active on the consensus layer&lt;&#x2F;li&gt;
&lt;li&gt;Verifiable signature&lt;&#x2F;li&gt;
&lt;li&gt;A single change operation for a single validator, with all required fields in the file with no other content present&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All merge requests that fail will be provided a reason from above which must be addressed prior to merge. Any future verifiable amendments to accepted claims must be proposed by the same submitter, or it will be treated as a contention.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;blstoexecutionchange-broadcast&quot;&gt;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&lt;&#x2F;h4&gt;
&lt;p&gt;Anyone in the community will be able to independently verify the files from the claims provided using the Capella spec and command line clients such as &quot;ethdo&quot; which support the specification.&lt;&#x2F;p&gt;
&lt;p&gt;A claim will be considered contested if a claim arrives where the verifiable consensus layer signatures differ between two or more submissions, where neither party has proven ownership of the execution layer deposit address. If a contested but verified &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; request arrives to a repository, all parties can be notified, and may try to convince the wider community by providing any publicly verifiable on chain evidence or off chain evidence supporting their claim to then include their claim in nodes. Node operators may decide which verifiable claims they wish to include based on social consensus.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-attacker-lacks-el-deposit-key-uncontested-claim&quot;&gt;1: Attacker lacks EL deposit key, uncontested claim&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Controls the CL keys and the EL key used for the deposit&lt;&#x2F;li&gt;
&lt;li&gt;User B: Controls the CL keys, but does not control the EL key for the deposit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;User A signs and submits a claim to the CLWP repository, clients load User A message into the &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; file. At the time of the first epoch support &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt;, many (not all) nodes begin to broadcast the message. User B also tries to submit a different but valid &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; to an address that does not match the signature in the claim. This message is successfully received via REST API, but some (not all) nodes begin to silently drop this message as the signature does not match the signature in the &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; file. As such, these nodes do not replicate this message via P2P.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-attacker-has-both-el-deposit-key-and-cl-keys-uncontested-claim&quot;&gt;2: Attacker has both EL deposit key and CL keys, uncontested claim&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Controls the CL key&#x2F;mnemonic and the EL key used for the deposit, and submits a claim to move to a new address&lt;&#x2F;li&gt;
&lt;li&gt;User B: Controls the CL and EL key&#x2F;mnemonic used for the EL deposit, but fails to submit a claim&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is possible&#x2F;likely that User A would notice that all their funds in the EL deposit address had been stolen. This may signal that their CL key is compromised as well, so they decide to pick a new address for the withdrawal. The story will play out the same as Scenario 1 as the claim is uncontested.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-same-as-2-but-the-attacker-submits-a-contested-claim&quot;&gt;3: Same as #2, but the attacker submits a contested claim&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Controls the CL keys&#x2F;mnemonic and the EL key used for the deposit, and submits a claim to move to a new address&lt;&#x2F;li&gt;
&lt;li&gt;User B: Controls the CL keys&#x2F;mnemonic and the EL key used for the deposit, and submits a claim to move to a new address&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is a contested claim and as such there is no way to prove who is in control using on chain data. Instead, either user may try to persuade the community they are the rightful owner (identity verification, social media, etc.) in an attempt to get node operators to load their contested claim into their &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; file. However, there is no way to fully prove it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-a-user-has-lost-either-their-cl-key-and-or-mnemonic-no-withdrawal-key&quot;&gt;4: A user has lost either their CL key and&#x2F;or mnemonic (no withdrawal key)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Lacks the CL keys and mnemonic&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is no way to recover this scenario with this proposal as we cannot prove a user has lost their keys, and the mnemonic is required to generate the withdrawal key.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;5-end-game-attacker&quot;&gt;5: End game - attacker&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Controls EL and CL key&#x2F;mnemonic, successfully achieves a set address withdrawal&lt;&#x2F;li&gt;
&lt;li&gt;User B: Controls CL key, decides to attack&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Upon noticing User A has submitted a successful set address withdrawal, User B may run a validator and attempt to get User A slashed. Users who suspect their validator key or seed phrase is compromised should take action to exit their validator as early as possible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;6-compromised-key-but-not-vulnerable-to-withdrawal&quot;&gt;6: Compromised key, but not vulnerable to withdrawal&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Controls EL and CL key&#x2F;mnemonic, but has a vulnerability which leaks their CL key but NOT their CL mnemonic&lt;&#x2F;li&gt;
&lt;li&gt;User B: Controls the CL key, but lacks the CL mnemonic&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;User A may generate the withdrawal key (requires the mnemonic). User B can attack User A by getting them slashed, but will be unable to generate the withdrawal key.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;7-attacker-loads-a-malicious-blstoexecutionchange-broadcast-file-into-one-or-multiple-nodes-user-a-submits-claim&quot;&gt;7: Attacker loads a malicious &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast file into one or multiple nodes, User A submits claim&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User A: Submits a valid uncontested claim which is broadcast out as soon as possible by many nodes&lt;&#x2F;li&gt;
&lt;li&gt;User B: Submits no claim, but broadcasts a valid malicious claim out through their &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast list, and blocks User A&#x27;s claim from their node.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;User B&#x27;s claim will make it into many nodes, but when it hits nodes that have adopted User A&#x27;s signature they will be dropped and not rebroadcast. Statistically, User B will have a harder time achieving consensus among the entire community, but it will be down to chance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;8-same-as-7-but-user-a-submits-no-claim&quot;&gt;8: Same as #7, but User A submits no claim&lt;&#x2F;h3&gt;
&lt;p&gt;The attacker will statistically likely win as they will be first to have their message broadcast to many nodes and, unless User A submits a request exactly at the time of support, it is unlikely to be heard by enough nodes to gain consensus. All users are encouraged to submit claims for this reason because nobody can be certain their mnemonic has not been compromised until it is too late.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;second-order-effects&quot;&gt;Second Order Effects&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;A user who participates in the &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; may cause the attacker to give up early and instead start to slash. For some users, the thought of getting slashed is preferable to giving an adversary any funds. As the proposal is voluntary, users may choose not to participate if they fear this scenario.&lt;&#x2F;li&gt;
&lt;li&gt;The attacker may set up their own &lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast to reject signatures not matching their attack. This is possible with or without this proposal.&lt;&#x2F;li&gt;
&lt;li&gt;The attacker may be the one collecting &quot;&lt;code&gt;BLSToExecutionChange&lt;&#x2F;code&gt; Broadcast&quot; claims for this proposal and may purposefully reject legitimate requests. Anyone is free to set up their own community claim collection and gather their own community support using the same mechanisms described in this proposal to form an alternative social consensus.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Shareable Non-Fungible Token</title>
        <published>2022-01-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Jarno Marttila</name><uri>https://github.com/yaruno</uri>
	</author>
	
	<author>
		<name>Martin Moravek</name><uri>https://github.com/mmartinmo</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5023/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/new-nft-concept-shareable-nfts/8681" />
        

        <id>https://wg-eips.ritovision.com/5023/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5023"
            label="ERC-5023" />
        

        
        

        
        <summary type="html">An interface for creating value-holding tokens shareable by multiple owners</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5023/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes an interface for non-fungible value-holding shareable tokens. Shareability is accomplished by minting copies of existing tokens for new recipients. Sharing and associated events allow the construction of a graph describing who has shared what to which party.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;NFT standards such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt; have been developed to standardize scarce digital resources. However, many non-fungible digital resources need not be scarce.&lt;&#x2F;p&gt;
&lt;p&gt;We have attempted to capture positive externalities in ecosystems with new types of incentive mechanisms that exhibit anti-rival logic, serve as an unit of accounting and function as medium of sharing. We envision that shareable tokens can work both as incentives but also as representations of items that are typically digital in their nature and gain more value as they are shared.&lt;&#x2F;p&gt;
&lt;p&gt;These requirements have set us to define shareable NFTs and more specifically a variation of shareable NFTs called non-transferable shareable NFTs. These shareable NFTs can be “shared” in the same way digital goods can be shared, at an almost zero technical transaction cost. We have utilized them to capture anti-rival value in terms of accounting positive externalities in an economic system.&lt;&#x2F;p&gt;
&lt;p&gt;Typical NFT standards such as EIP-721 and EIP-1155 do not define a sharing modality. Instead ERC standards define interfaces for typical rival use cases such as token minting and token transactions that the NFT contract implementations should fulfil. The ‘standard contract implementations&#x27; may extend the functionalities of these standards beyond the definition of interfaces. The shareable tokens that we have designed and developed in our experiments are designed to be token standard compatible at the interface level. However the implementation of token contracts may contain extended functionalities to match the requirements of the experiments such as the requirement of &#x27;shareability&#x27;. In reflection to standard token definitions, shareability of a token could be thought of as re-mintability of an existing token to another party while retaining the original version of it.&lt;&#x2F;p&gt;
&lt;p&gt;Sharing is an interesting concept as it can be thought and perceived in different ways. For example, when we talk about sharing we can think about it is as digital copying, giving a copy of a digital resource while retaining a version by ourselves. Sharing can also be fractional or sharing could be about giving rights to use a certain resource. The concept of shareability and the context of shareability can take different forms and one might use different types of implementatins for instances of shareable tokens. Hence we haven&#x27;t restricted that the interface should require any specific token type.&lt;&#x2F;p&gt;
&lt;p&gt;Shareable tokens can be made non-transferable at the contract implementation level. Doing so, makes them shareable non-transferable tokens. In the reference implementation we have distilled a general case from our use cases that defines a shareable non-transferable NFTs using the shareable NFT interface.&lt;&#x2F;p&gt;
&lt;p&gt;We believe that the wider audience should benefit from an abstraction level higher definition for shareability, such as this interface implementation, that defines minimum amount of functions that would be implemented to satisfy the concept of shareability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xded6338b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC5023&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when a token is shared, reminted and given to another wallet that isn&amp;#39;t function caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Share&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; derivedFromtokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Shares, remints an existing token, gives a newly minted token a fresh token id, keeps original token at function callers possession and transfers newly minted token to receiver which should be another address than function caller. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; share&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newTokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&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 Share event is expected to be emitted when function method share is successfully called and a new token on basis of a given token id is minted and transferred to a recipient.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Current NFT standards define transferable non-fungible tokens, but not shareable non-fungible tokens. To be able to create shareable NFTs we see that existing NFT contracts could be extended with an interface which defines the basic principles of sharing, namely the Event of sharing and the function method of sharing. Definition of how transferability of tokens should be handled is left to the contract implementor. In case transferring is left enable shareable tokens behave similarly to the existing tokens, except when they are shared, a version of token is retained. In case transfering is disabled, shareable tokens become shareable non-transferable tokens, where they can be minted and given or shared to other people, but they cannot be transferred away.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine that Bob works together with Alice on a project. Bob earns an unique NFT indicating that he has made effort to the project, but Bob feels that his accomplishments are not only out of his own accord. Bob wants to share his token with Alice to indicate that also Alice deserves recognition of having put effort on their project. Bob initiates token sharing by calling &lt;code&gt;Share&lt;&#x2F;code&gt; method on the contract which has his token and indicates which one of his tokens he wishes to share and to whom by passing address and token id parameters. A new token is minted for Alice and a &lt;code&gt;Share&lt;&#x2F;code&gt; event is initiated to communicate that it was Bob whom shared his token to Alice by logging addresses who shared a token id to whose address and which token id was this new token derived from.&lt;&#x2F;p&gt;
&lt;p&gt;Over time, a tree-like structures can be formed from the Share event information. If Bob shared to Alice, and Alice shared further to Charlie and Alice also shared to David a rudimentary tree structure forms out from sharing activity. This share event data can be later on utilized to gain more information of share activities that the tokens represent.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;B -&amp;gt; A -&amp;gt; C &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;       &amp;gt;  D&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These tree structures can be further aggregated and collapsed to network representations e.g. social graphs on basis of whom has shared to whom over a span of time. E.g. if Bob shared a token to Alice, and Alice has shared a different token to Charlie and Bob has shared a token to Charlie, connections form between all these parties through sharing activities.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; B----A----C         &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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is backwards compatible with EIP-721 and EIP-1155.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Following reference implementation demonstrates a general use case of one of our pilots. In this case a shareable non-transferable token represents a contribution done to a community that the contract owner has decided to merit with a token. Contract owner can mint a merit token and give it to a person. This token can be further shared by the receiver to other parties for example to share the received merit to others that have participated or influenced his contribution.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; SPDX-License-Identifier: CC0-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC5023.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;IERC721.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;IERC721Receiver.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;Address.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;Context.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;Strings.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;introspection&#x2F;ERC165.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;extensions&#x2F;IERC721Metadata.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;extensions&#x2F;ERC721URIStorage.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;access&#x2F;Ownable.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ShareableERC721&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721URIStorage&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Ownable&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC5023&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;EIP165&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;  string&lt;&#x2F;span&gt;&lt;span&gt; baseURI&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; _currentIndex&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_name, _symbol) &lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-entity z-name&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenURI&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 class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        _setTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setBaseURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; baseURI_&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        baseURI &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; baseURI_&lt;&#x2F;span&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;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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _baseURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; baseURI&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; share&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newTokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC721: mint to the zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ShareableERC721: token to be shared must exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Method caller must be the owner of token&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _tokenURI &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _currentIndex&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      _setTokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_currentIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _tokenURI&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Share&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _currentIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tokenIdToBeShared&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt; _currentIndex&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;In this reference implementation tokens are not transferrable&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&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 class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;In this reference implementation tokens are not transferrable&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Reference implementation should not be used as is in production.
There are no other security considerations related directly to implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Tokenized Vaults</title>
        <published>2021-12-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Joey Santoro</name><uri>https://github.com/joeysantoro</uri>
	</author>
	
	<author>
		<name>t11s</name><uri>https://github.com/transmissions11</uri>
	</author>
	
	<author>
		<name>Jet Jadeja</name><uri>https://github.com/JetJadeja</uri>
	</author>
	
	<author>
		<name>Alberto Cuesta Cañada</name><uri>https://github.com/alcueca</uri>
	</author>
	
	<author>
		<name>Señor Doggo</name><uri>https://github.com/fubuloubu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4626/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4626-yield-bearing-vault-standard/7900" />
        

        <id>https://wg-eips.ritovision.com/4626/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4626"
            label="ERC-4626" />
        

        
        

        
        <summary type="html">Tokenized Vaults with a single underlying EIP-20 token.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4626/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard allows for the implementation of a standard API for tokenized Vaults
representing shares of a single underlying &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; token.
This standard is an extension on the EIP-20 token that provides basic functionality for depositing
and withdrawing tokens and reading balances.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Tokenized Vaults have a lack of standardization leading to diverse implementation details.
Some various examples include lending markets, aggregators, and intrinsically interest bearing tokens.
This makes integration difficult at the aggregator or plugin layer for protocols which need to conform to many standards, and forces each protocol to implement their own adapters which are error prone and waste development resources.&lt;&#x2F;p&gt;
&lt;p&gt;A standard for tokenized Vaults will lower the integration effort for yield-bearing vaults, while creating more consistent and robust implementation patterns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;All &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4626&#x2F;&quot;&gt;EIP-4626&lt;&#x2F;a&gt; tokenized Vaults MUST implement EIP-20 to represent shares.
If a Vault is to be non-transferrable, it MAY revert on calls to &lt;code&gt;transfer&lt;&#x2F;code&gt; or &lt;code&gt;transferFrom&lt;&#x2F;code&gt;.
The EIP-20 operations &lt;code&gt;balanceOf&lt;&#x2F;code&gt;, &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;totalSupply&lt;&#x2F;code&gt;, etc. operate on the Vault &quot;shares&quot;
which represent a claim to ownership on a fraction of the Vault&#x27;s underlying holdings.&lt;&#x2F;p&gt;
&lt;p&gt;All EIP-4626 tokenized Vaults MUST implement EIP-20&#x27;s optional metadata extensions.
The &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; functions SHOULD reflect the underlying token&#x27;s &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; in some way.&lt;&#x2F;p&gt;
&lt;p&gt;EIP-4626 tokenized Vaults MAY implement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2612&#x2F;&quot;&gt;EIP-2612&lt;&#x2F;a&gt; to improve the UX of approving shares on various integrations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions:&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;asset: The underlying token managed by the Vault.
Has units defined by the corresponding EIP-20 contract.&lt;&#x2F;li&gt;
&lt;li&gt;share: The token of the Vault. Has a ratio of underlying assets
exchanged on mint&#x2F;deposit&#x2F;withdraw&#x2F;redeem (as defined by the Vault).&lt;&#x2F;li&gt;
&lt;li&gt;fee: An amount of assets or shares charged to the user by the Vault. Fees can exists for
deposits, yield, AUM, withdrawals, or anything else prescribed by the Vault.&lt;&#x2F;li&gt;
&lt;li&gt;slippage: Any difference between advertised share price and economic realities of
deposit to or withdrawal from the Vault, which is not accounted by fees.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;asset&quot;&gt;asset&lt;&#x2F;h4&gt;
&lt;p&gt;The address of the underlying token used for the Vault for accounting, depositing, and withdrawing.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be an EIP-20 token contract.&lt;&#x2F;p&gt;
&lt;p&gt;MUST &lt;em&gt;NOT&lt;&#x2F;em&gt; revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssetTokenAddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;totalassets&quot;&gt;totalAssets&lt;&#x2F;h4&gt;
&lt;p&gt;Total amount of the underlying asset that is &quot;managed&quot; by Vault.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD include any compounding that occurs from yield.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be inclusive of any fees that are charged against assets in the Vault.&lt;&#x2F;p&gt;
&lt;p&gt;MUST &lt;em&gt;NOT&lt;&#x2F;em&gt; revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;otalAssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;otalManagedAssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;converttoshares&quot;&gt;convertToShares&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of shares that the Vault would exchange for the amount of assets provided, in an ideal scenario where all the conditions are met.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT be inclusive of any fees that are charged against assets in the Vault.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;p&gt;MUST round down towards 0.&lt;&#x2F;p&gt;
&lt;p&gt;This calculation MAY NOT reflect the &quot;per-user&quot; price-per-share, and instead should reflect the &quot;average-user&#x27;s&quot; price-per-share, meaning what the average user should expect to see when exchanging to and from.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onvertToShares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;converttoassets&quot;&gt;convertToAssets&lt;&#x2F;h4&gt;
&lt;p&gt;The amount of assets that the Vault would exchange for the amount of shares provided, in an ideal scenario where all the conditions are met.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT be inclusive of any fees that are charged against assets in the Vault.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT show any variations depending on the caller.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert unless due to integer overflow caused by an unreasonably large input.&lt;&#x2F;p&gt;
&lt;p&gt;MUST round down towards 0.&lt;&#x2F;p&gt;
&lt;p&gt;This calculation MAY NOT reflect the &quot;per-user&quot; price-per-share, and instead should reflect the &quot;average-user&#x27;s&quot; price-per-share, meaning what the average user should expect to see when exchanging to and from.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onvertToAssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;maxdeposit&quot;&gt;maxDeposit&lt;&#x2F;h4&gt;
&lt;p&gt;Maximum amount of the underlying asset that can be deposited into the Vault for the &lt;code&gt;receiver&lt;&#x2F;code&gt;, through a &lt;code&gt;deposit&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return the maximum amount of assets &lt;code&gt;deposit&lt;&#x2F;code&gt; would allow to be deposited for &lt;code&gt;receiver&lt;&#x2F;code&gt; and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary). This assumes that the user has infinite assets, i.e. MUST NOT rely on &lt;code&gt;balanceOf&lt;&#x2F;code&gt; of &lt;code&gt;asset&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST factor in both global and user-specific limits, like if deposits are entirely disabled (even temporarily) it MUST return 0.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return &lt;code&gt;2 ** 256 - 1&lt;&#x2F;code&gt; if there is no limit on the maximum amount of assets that may be deposited.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axDeposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axAssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;previewdeposit&quot;&gt;previewDeposit&lt;&#x2F;h4&gt;
&lt;p&gt;Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given current on-chain conditions.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return as close to and no more than the exact amount of Vault shares that would be minted in a &lt;code&gt;deposit&lt;&#x2F;code&gt; call in the same transaction. I.e. &lt;code&gt;deposit&lt;&#x2F;code&gt; should return the same or more &lt;code&gt;shares&lt;&#x2F;code&gt; as &lt;code&gt;previewDeposit&lt;&#x2F;code&gt; if called in the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the deposit would be accepted, regardless if the user has enough tokens approved, etc.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert due to vault specific user&#x2F;global limits. MAY revert due to other conditions that would also cause &lt;code&gt;deposit&lt;&#x2F;code&gt; to revert.&lt;&#x2F;p&gt;
&lt;p&gt;Note that any unfavorable discrepancy between &lt;code&gt;convertToShares&lt;&#x2F;code&gt; and &lt;code&gt;previewDeposit&lt;&#x2F;code&gt; SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by depositing.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;reviewDeposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;deposit&quot;&gt;deposit&lt;&#x2F;h4&gt;
&lt;p&gt;Mints &lt;code&gt;shares&lt;&#x2F;code&gt; Vault shares to &lt;code&gt;receiver&lt;&#x2F;code&gt; by depositing exactly &lt;code&gt;assets&lt;&#x2F;code&gt; of underlying tokens.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Deposit&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support EIP-20 &lt;code&gt;approve&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;transferFrom&lt;&#x2F;code&gt; on &lt;code&gt;asset&lt;&#x2F;code&gt; as a deposit flow.
MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the &lt;code&gt;deposit&lt;&#x2F;code&gt; execution, and are accounted for during &lt;code&gt;deposit&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;assets&lt;&#x2F;code&gt; cannot be deposited (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Note that most implementations will require pre-approval of the Vault with the Vault&#x27;s underlying &lt;code&gt;asset&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;maxmint&quot;&gt;maxMint&lt;&#x2F;h4&gt;
&lt;p&gt;Maximum amount of shares that can be minted from the Vault for the &lt;code&gt;receiver&lt;&#x2F;code&gt;, through a &lt;code&gt;mint&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return the maximum amount of shares &lt;code&gt;mint&lt;&#x2F;code&gt; would allow to be deposited to &lt;code&gt;receiver&lt;&#x2F;code&gt; and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary). This assumes that the user has infinite assets, i.e. MUST NOT rely on &lt;code&gt;balanceOf&lt;&#x2F;code&gt; of &lt;code&gt;asset&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST factor in both global and user-specific limits, like if mints are entirely disabled (even temporarily) it MUST return 0.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return &lt;code&gt;2 ** 256 - 1&lt;&#x2F;code&gt; if there is no limit on the maximum amount of shares that may be minted.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axMint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axShares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;previewmint&quot;&gt;previewMint&lt;&#x2F;h4&gt;
&lt;p&gt;Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given current on-chain conditions.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return as close to and no fewer than the exact amount of assets that would be deposited in a &lt;code&gt;mint&lt;&#x2F;code&gt; call in the same transaction. I.e. &lt;code&gt;mint&lt;&#x2F;code&gt; should return the same or fewer &lt;code&gt;assets&lt;&#x2F;code&gt; as &lt;code&gt;previewMint&lt;&#x2F;code&gt; if called in the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint would be accepted, regardless if the user has enough tokens approved, etc.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert due to vault specific user&#x2F;global limits. MAY revert due to other conditions that would also cause &lt;code&gt;mint&lt;&#x2F;code&gt; to revert.&lt;&#x2F;p&gt;
&lt;p&gt;Note that any unfavorable discrepancy between &lt;code&gt;convertToAssets&lt;&#x2F;code&gt; and &lt;code&gt;previewMint&lt;&#x2F;code&gt; SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by minting.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;reviewMint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;mint&quot;&gt;mint&lt;&#x2F;h4&gt;
&lt;p&gt;Mints exactly &lt;code&gt;shares&lt;&#x2F;code&gt; Vault shares to &lt;code&gt;receiver&lt;&#x2F;code&gt; by depositing &lt;code&gt;assets&lt;&#x2F;code&gt; of underlying tokens.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Deposit&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support EIP-20 &lt;code&gt;approve&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;transferFrom&lt;&#x2F;code&gt; on &lt;code&gt;asset&lt;&#x2F;code&gt; as a mint flow.
MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the &lt;code&gt;mint&lt;&#x2F;code&gt; execution, and are accounted for during &lt;code&gt;mint&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;shares&lt;&#x2F;code&gt; cannot be minted (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Note that most implementations will require pre-approval of the Vault with the Vault&#x27;s underlying &lt;code&gt;asset&lt;&#x2F;code&gt; token.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;maxwithdraw&quot;&gt;maxWithdraw&lt;&#x2F;h4&gt;
&lt;p&gt;Maximum amount of the underlying asset that can be withdrawn from the &lt;code&gt;owner&lt;&#x2F;code&gt; balance in the Vault, through a &lt;code&gt;withdraw&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return the maximum amount of assets that could be transferred from &lt;code&gt;owner&lt;&#x2F;code&gt; through &lt;code&gt;withdraw&lt;&#x2F;code&gt; and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).&lt;&#x2F;p&gt;
&lt;p&gt;MUST factor in both global and user-specific limits, like if withdrawals are entirely disabled (even temporarily) it MUST return 0.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axWithdraw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axAssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;previewwithdraw&quot;&gt;previewWithdraw&lt;&#x2F;h4&gt;
&lt;p&gt;Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, given current on-chain conditions.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a &lt;code&gt;withdraw&lt;&#x2F;code&gt; call in the same transaction. I.e. &lt;code&gt;withdraw&lt;&#x2F;code&gt; should return the same or fewer &lt;code&gt;shares&lt;&#x2F;code&gt; as &lt;code&gt;previewWithdraw&lt;&#x2F;code&gt; if called in the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though the withdrawal would be accepted, regardless if the user has enough shares, etc.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert due to vault specific user&#x2F;global limits. MAY revert due to other conditions that would also cause &lt;code&gt;withdraw&lt;&#x2F;code&gt; to revert.&lt;&#x2F;p&gt;
&lt;p&gt;Note that any unfavorable discrepancy between &lt;code&gt;convertToShares&lt;&#x2F;code&gt; and &lt;code&gt;previewWithdraw&lt;&#x2F;code&gt; SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by depositing.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;reviewWithdraw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;withdraw&quot;&gt;withdraw&lt;&#x2F;h4&gt;
&lt;p&gt;Burns &lt;code&gt;shares&lt;&#x2F;code&gt; from &lt;code&gt;owner&lt;&#x2F;code&gt; and sends exactly &lt;code&gt;assets&lt;&#x2F;code&gt; of underlying tokens to &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Withdraw&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support a withdraw flow where the shares are burned from &lt;code&gt;owner&lt;&#x2F;code&gt; directly where &lt;code&gt;owner&lt;&#x2F;code&gt; is &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support a withdraw flow where the shares are burned from &lt;code&gt;owner&lt;&#x2F;code&gt; directly where &lt;code&gt;msg.sender&lt;&#x2F;code&gt; has EIP-20 approval over the shares of &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MAY support an additional flow in which the shares are transferred to the Vault contract before the &lt;code&gt;withdraw&lt;&#x2F;code&gt; execution, and are accounted for during &lt;code&gt;withdraw&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD check &lt;code&gt;msg.sender&lt;&#x2F;code&gt; can spend owner funds, assets needs to be converted to shares and shares should be checked for allowance.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;assets&lt;&#x2F;code&gt; cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner not having enough shares, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. Those methods should be performed separately.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ithdraw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;maxredeem&quot;&gt;maxRedeem&lt;&#x2F;h4&gt;
&lt;p&gt;Maximum amount of Vault shares that can be redeemed from the &lt;code&gt;owner&lt;&#x2F;code&gt; balance in the Vault, through a &lt;code&gt;redeem&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return the maximum amount of shares that could be transferred from &lt;code&gt;owner&lt;&#x2F;code&gt; through &lt;code&gt;redeem&lt;&#x2F;code&gt; and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).&lt;&#x2F;p&gt;
&lt;p&gt;MUST factor in both global and user-specific limits, like if redemption is entirely disabled (even temporarily) it MUST return 0.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axRedeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;axShares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;previewredeem&quot;&gt;previewRedeem&lt;&#x2F;h4&gt;
&lt;p&gt;Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, given current on-chain conditions.&lt;&#x2F;p&gt;
&lt;p&gt;MUST return as close to and no more than the exact amount of assets that would be withdrawn in a &lt;code&gt;redeem&lt;&#x2F;code&gt; call in the same transaction. I.e. &lt;code&gt;redeem&lt;&#x2F;code&gt; should return the same or more &lt;code&gt;assets&lt;&#x2F;code&gt; as &lt;code&gt;previewRedeem&lt;&#x2F;code&gt; if called in the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the redemption would be accepted, regardless if the user has enough shares, etc.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.&lt;&#x2F;p&gt;
&lt;p&gt;MUST NOT revert due to vault specific user&#x2F;global limits. MAY revert due to other conditions that would also cause &lt;code&gt;redeem&lt;&#x2F;code&gt; to revert.&lt;&#x2F;p&gt;
&lt;p&gt;Note that any unfavorable discrepancy between &lt;code&gt;convertToAssets&lt;&#x2F;code&gt; and &lt;code&gt;previewRedeem&lt;&#x2F;code&gt; SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by redeeming.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;reviewRedeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;iew&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;redeem&quot;&gt;redeem&lt;&#x2F;h4&gt;
&lt;p&gt;Burns exactly &lt;code&gt;shares&lt;&#x2F;code&gt; from &lt;code&gt;owner&lt;&#x2F;code&gt; and sends &lt;code&gt;assets&lt;&#x2F;code&gt; of underlying tokens to &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST emit the &lt;code&gt;Withdraw&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support a redeem flow where the shares are burned from &lt;code&gt;owner&lt;&#x2F;code&gt; directly where &lt;code&gt;owner&lt;&#x2F;code&gt; is &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST support a redeem flow where the shares are burned from &lt;code&gt;owner&lt;&#x2F;code&gt; directly where &lt;code&gt;msg.sender&lt;&#x2F;code&gt; has EIP-20 approval over the shares of &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MAY support an additional flow in which the shares are transferred to the Vault contract before the &lt;code&gt;redeem&lt;&#x2F;code&gt; execution, and are accounted for during &lt;code&gt;redeem&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;SHOULD check &lt;code&gt;msg.sender&lt;&#x2F;code&gt; can spend owner funds using allowance.&lt;&#x2F;p&gt;
&lt;p&gt;MUST revert if all of &lt;code&gt;shares&lt;&#x2F;code&gt; cannot be redeemed (due to withdrawal limit being reached, slippage, the owner not having enough shares, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. Those methods should be performed separately.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;edeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tateMutability&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;onpayable&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;utputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;deposit-1&quot;&gt;Deposit&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;sender&lt;&#x2F;code&gt; has exchanged &lt;code&gt;assets&lt;&#x2F;code&gt; for &lt;code&gt;shares&lt;&#x2F;code&gt;, and transferred those &lt;code&gt;shares&lt;&#x2F;code&gt; to &lt;code&gt;owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be emitted when tokens are deposited into the Vault via the &lt;code&gt;mint&lt;&#x2F;code&gt; and &lt;code&gt;deposit&lt;&#x2F;code&gt; methods.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;withdraw-1&quot;&gt;Withdraw&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;sender&lt;&#x2F;code&gt; has exchanged &lt;code&gt;shares&lt;&#x2F;code&gt;, owned by &lt;code&gt;owner&lt;&#x2F;code&gt;, for &lt;code&gt;assets&lt;&#x2F;code&gt;, and transferred those &lt;code&gt;assets&lt;&#x2F;code&gt; to &lt;code&gt;receiver&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;MUST be emitted when shares are withdrawn from the Vault in &lt;code&gt;EIP-4626.redeem&lt;&#x2F;code&gt; or &lt;code&gt;EIP-4626.withdraw&lt;&#x2F;code&gt; methods.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; W&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ithdraw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;vent&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 class=&quot;z-entity z-name z-tag&quot;&gt;  i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nputs&lt;&#x2F;span&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;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eceiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ddress&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&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 class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ndexed&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ype&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;int256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The Vault interface is designed to be optimized for integrators with a feature complete yet minimal interface.
Details such as accounting and allocation of deposited tokens are intentionally not specified,
as Vaults are expected to be treated as black boxes on-chain and inspected off-chain before use.&lt;&#x2F;p&gt;
&lt;p&gt;EIP-20 is enforced because implementation details like token approval
and balance calculation directly carry over to the shares accounting.
This standardization makes the Vaults immediately compatible with all EIP-20 use cases in addition to EIP-4626.&lt;&#x2F;p&gt;
&lt;p&gt;The mint method was included for symmetry and feature completeness.
Most current use cases of share-based Vaults do not ascribe special meaning to the shares such that
a user would optimize for a specific number of shares (&lt;code&gt;mint&lt;&#x2F;code&gt;) rather than specific amount of underlying (&lt;code&gt;deposit&lt;&#x2F;code&gt;).
However, it is easy to imagine future Vault strategies which would have unique and independently useful share representations.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;convertTo&lt;&#x2F;code&gt; functions serve as rough estimates that do not account for operation specific details like withdrawal fees, etc.
They were included for frontends and applications that need an average value of shares or assets, not an exact value possibly including slippage or other fees.
For applications that need an exact value that attempts to account for fees and slippage we have included a corresponding &lt;code&gt;preview&lt;&#x2F;code&gt; function to match each mutable function. These functions must not account for deposit or withdrawal limits, to ensure they are easily composable, the &lt;code&gt;max&lt;&#x2F;code&gt; functions are provided for that purpose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;EIP-4626 is fully backward compatible with the EIP-20 standard and has no known compatibility issues with other standards.
For production implementations of Vaults which do not use EIP-4626, wrapper adapters can be developed and used.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;transmissions11&#x2F;solmate&#x2F;blob&#x2F;main&#x2F;src&#x2F;tokens&#x2F;ERC4626.sol&quot;&gt;Solmate EIP-4626&lt;&#x2F;a&gt;:
a minimal and opinionated implementation of the standard with hooks for developers to easily insert custom logic into deposits and withdrawals.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fubuloubu&#x2F;ERC4626&quot;&gt;Vyper EIP-4626&lt;&#x2F;a&gt;:
a demo implementation of the standard in Vyper, with hooks for share price manipulation and other testing needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Fully permissionless use cases could fall prey to malicious implementations which only conform to the interface but not the specification.
It is recommended that all integrators review the implementation for potential ways of losing user deposits before integrating.&lt;&#x2F;p&gt;
&lt;p&gt;If implementors intend to support EOA account access directly, they should consider adding an additional function call for &lt;code&gt;deposit&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;mint&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;withdraw&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;redeem&lt;&#x2F;code&gt; with the means to accommodate slippage loss or unexpected deposit&#x2F;withdrawal limits, since they have no other means to revert the transaction if the exact output amount is not achieved.&lt;&#x2F;p&gt;
&lt;p&gt;The methods &lt;code&gt;totalAssets&lt;&#x2F;code&gt;, &lt;code&gt;convertToShares&lt;&#x2F;code&gt; and &lt;code&gt;convertToAssets&lt;&#x2F;code&gt; are estimates useful for display purposes,
and do &lt;em&gt;not&lt;&#x2F;em&gt; have to confer the &lt;em&gt;exact&lt;&#x2F;em&gt; amount of underlying assets their context suggests.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;preview&lt;&#x2F;code&gt; methods return values that are as close as possible to exact as possible. For that reason, they are manipulable by altering the on-chain conditions and are not always safe to be used as price oracles. This specification includes &lt;code&gt;convert&lt;&#x2F;code&gt; methods that are allowed to be inexact and therefore can be implemented as robust price oracles. For example, it would be correct to implement the &lt;code&gt;convert&lt;&#x2F;code&gt; methods as using a time-weighted average price in converting between assets and shares.&lt;&#x2F;p&gt;
&lt;p&gt;Integrators of EIP-4626 Vaults should be aware of the difference between these view methods when integrating with this standard. Additionally, note that the amount of underlying assets a user may receive from redeeming their Vault shares (&lt;code&gt;previewRedeem&lt;&#x2F;code&gt;) can be significantly different than the amount that would be taken from them when minting the same quantity of shares (&lt;code&gt;previewMint&lt;&#x2F;code&gt;). The differences may be small (like if due to rounding error), or very significant (like if a Vault implements withdrawal or deposit fees, etc). Therefore integrators should always take care to use the preview function most relevant to their use case, and never assume they are interchangeable.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, EIP-4626 Vault implementers should be aware of the need for specific, opposing rounding directions across the different mutable and view methods, as it is considered most secure to favor the Vault itself during calculations over its users:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If (1) it&#x27;s calculating how many shares to issue to a user for a certain amount of the underlying tokens they provide or (2) it&#x27;s determining the amount of the underlying tokens to transfer to them for returning a certain amount of shares, it should round &lt;em&gt;down&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If (1) it&#x27;s calculating the amount of shares a user has to supply to receive a given amount of the underlying tokens or (2) it&#x27;s calculating the amount of underlying tokens a user has to provide to receive a certain amount of shares, it should round &lt;em&gt;up&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The only functions where the preferred rounding direction would be ambiguous are the &lt;code&gt;convertTo&lt;&#x2F;code&gt; functions. To ensure consistency across all EIP-4626 Vault implementations it is specified that these functions MUST both always round &lt;em&gt;down&lt;&#x2F;em&gt;. Integrators may wish to mimic rounding up versions of these functions themselves, like by adding 1 wei to the result.&lt;&#x2F;p&gt;
&lt;p&gt;Although the &lt;code&gt;convertTo&lt;&#x2F;code&gt; functions should eliminate the need for any use of an EIP-4626 Vault&#x27;s &lt;code&gt;decimals&lt;&#x2F;code&gt; variable, it is still strongly recommended to mirror
the underlying token&#x27;s &lt;code&gt;decimals&lt;&#x2F;code&gt; if at all possible, to eliminate possible sources of confusion and simplify integration across front-ends and for other off-chain users.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Non-Fungible Tokens Tied to Physical Assets</title>
        <published>2021-12-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Javier Arcenegui</name><uri>https://github.com/Hardblock-IMSE-CNM</uri>
	</author>
	
	<author>
		<name>Rosario Arjona</name><uri>https://github.com/RosarioArjona</uri>
	</author>
	
	<author>
		<name>Roberto Román</name><email>roman@imse-cnm.csic.es</email>
	</author>
	
	<author>
		<name>Iluminada Baturone</name><uri>https://github.com/lumi2018</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4519/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/new-proposal-of-smart-non-fungible-token/7677" />
        

        <id>https://wg-eips.ritovision.com/4519/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:4519"
            label="ERC-4519" />
        

        
        

        
        <summary type="html">Interface for non-fungible tokens representing physical assets that can generate or recover their own accounts and obey users.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4519/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes an interface for non-fungible tokens representing physical assets, such as Internet of Things (IoT) devices. These NFTs are tied to physical assets and can verify the authenticity of the tie. They can include an Ethereum address of the physical asset, permitting physical assets to sign messages and transactions. Physical assets can operate with an operating mode defined by its corresponding NFT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This standard was developed because &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; only tracks ownership (not usage rights) and does not track the Ethereum addresses of the asset. The popularity of smart assets, such as IoT devices, is increasing. To permit secure and traceable management, these NFTs can be used to establish secure communication channels between the physical asset, its owner, and its user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The attributes &lt;code&gt;addressAsset&lt;&#x2F;code&gt; and &lt;code&gt;addressUser&lt;&#x2F;code&gt; are, respectively, the Ethereum addresses of the physical asset and the user. They are optional attributes but at least one of them should be used in an NFT. In the case of using only the attribute &lt;code&gt;addressUser&lt;&#x2F;code&gt;, two states define if the token is assigned or not to a user. &lt;code&gt;Figure 1&lt;&#x2F;code&gt; shows these states in a flow chart. When a token is created, transferred or unassigned, the token state is set to &lt;code&gt;notAssigned&lt;&#x2F;code&gt;. If the token is assigned to a valid user, the state is set to &lt;code&gt;userAssigned&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;images&#x2F;Figure1.jpg&quot; alt=&quot;Figure 1 : Flow chart of the token states with addressUser defined (and addressAsset undefined)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the case of defining the attribute &lt;code&gt;addressAsset&lt;&#x2F;code&gt; but not the attribute &lt;code&gt;addressUser&lt;&#x2F;code&gt;, two states define if the token is waiting for authentication with the owner or if the authentication has finished successfully. &lt;code&gt;Figure 2&lt;&#x2F;code&gt; shows these states in a flow chart. When a token is created or transferred to a new owner, then the token changes its state to &lt;code&gt;waitingForOwner&lt;&#x2F;code&gt;. In this state, the token is waiting for the mutual authentication between the asset and the owner. Once authentication is finished successfully, the token changes its state to &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;images&#x2F;Figure2.jpg&quot; alt=&quot;Figure 2 : Flow chart of the token states with addressAsset defined (and addressUser undefined)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally, if both the attributes &lt;code&gt;addressAsset&lt;&#x2F;code&gt; and &lt;code&gt;addressUser&lt;&#x2F;code&gt; are defined, the states of the NFT define if the asset has been engaged or not with the owner or the user (&lt;code&gt;waitingForOwner&lt;&#x2F;code&gt;, &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt;, &lt;code&gt;waitingForUser&lt;&#x2F;code&gt; and &lt;code&gt;engagedWithUser&lt;&#x2F;code&gt;). The flow chart in &lt;code&gt;Figure 3&lt;&#x2F;code&gt; shows all the possible state changes. The states related to the owner are the same as in &lt;code&gt;Figure 2&lt;&#x2F;code&gt;. The difference is that, at the state &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt;, the token can be assigned to a user. If a user is assigned (the token being at states &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt;, &lt;code&gt;waitingForUser&lt;&#x2F;code&gt; or &lt;code&gt;engagedWithUser&lt;&#x2F;code&gt;), then the token changes its state to &lt;code&gt;waitingForUser&lt;&#x2F;code&gt;. Once the asset and the user authenticate each other, the state of the token is set to &lt;code&gt;engagedWithUser&lt;&#x2F;code&gt;, and the user is able to use the asset.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;images&#x2F;Figure3.jpg&quot; alt=&quot;Figure 3 : Flow chart of the token states with addressUser and addressUser defined&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In order to complete the ownership transfer of a token, the new owner must carry out a mutual authentication process with the asset, which is off-chain with the asset and on-chain with the token, by using their Ethereum addresses. Similarly, a new user must carry out a mutual authentication process with the asset to complete a use transfer. NFTs define how the authentication processes start and finish. These authentication processes allow deriving fresh session cryptographic keys for secure communication between assets and owners, and between assets and users. Therefore, the trustworthiness of the assets can be traced even if new owners and users manage them.&lt;&#x2F;p&gt;
&lt;p&gt;When the NFT is created or when the ownership is transferred, the token state is &lt;code&gt;waitingForOwner&lt;&#x2F;code&gt;. The asset sets its operating mode to &lt;code&gt;waitingForOwner&lt;&#x2F;code&gt;. The owner generates a pair of keys using the elliptic curve secp256k1 and the primitive element P used on this curve: a secret key SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; and a Public Key PK&lt;sub&gt;O_A&lt;&#x2F;sub&gt;, so that PK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; = SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; * P. To generate the shared key between the owner and the asset, K&lt;sub&gt;O&lt;&#x2F;sub&gt;, the public key of the asset, PK&lt;sub&gt;A&lt;&#x2F;sub&gt;, is employed as follows:&lt;&#x2F;p&gt;
&lt;p&gt;K&lt;sub&gt;O&lt;&#x2F;sub&gt; = PK&lt;sub&gt;A&lt;&#x2F;sub&gt; * SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the function &lt;code&gt;startOwnerEngagement&lt;&#x2F;code&gt;, PK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; is saved as the attribute &lt;code&gt;dataEngagement&lt;&#x2F;code&gt; and the hash of K&lt;sub&gt;O&lt;&#x2F;sub&gt; as the attribute &lt;code&gt;hashK_OA&lt;&#x2F;code&gt;. The owner sends request engagement to the asset, and the asset calculates:&lt;&#x2F;p&gt;
&lt;p&gt;K&lt;sub&gt;A&lt;&#x2F;sub&gt; = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * PK&lt;sub&gt;O_A&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If everything is correctly done, K&lt;sub&gt;O&lt;&#x2F;sub&gt; and K&lt;sub&gt;A&lt;&#x2F;sub&gt; are the same since:&lt;&#x2F;p&gt;
&lt;p&gt;K&lt;sub&gt;O&lt;&#x2F;sub&gt; = PK&lt;sub&gt;A&lt;&#x2F;sub&gt; * SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; = (SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * P) * SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * (SK&lt;sub&gt;O_A&lt;&#x2F;sub&gt; * P) = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * PK&lt;sub&gt;O_A&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the function &lt;code&gt;ownerEngagement&lt;&#x2F;code&gt;, the asset sends the hash of K&lt;sub&gt;A&lt;&#x2F;sub&gt;, and if it is the same as the data in &lt;code&gt;hashK_OA&lt;&#x2F;code&gt;, then the state of the token changes to &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt; and the event &lt;code&gt;OwnerEngaged&lt;&#x2F;code&gt; are sent. Once the asset receives the event, it changes its operation mode to &lt;code&gt;engagedWithOwner&lt;&#x2F;code&gt;. This process is shown in &lt;code&gt;Figure 4&lt;&#x2F;code&gt;. From this moment, the asset can be managed by the owner and they can communicate in a secure way using the shared key.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;images&#x2F;Figure4.jpg&quot; alt=&quot;Figure 4: Steps in a successful owner and asset mutual authentication process&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the asset consults Ethereum and the state of its NFT is &lt;code&gt;waitingForUser&lt;&#x2F;code&gt;, the asset (assuming it is an electronic physical asset) sets its operating mode to &lt;code&gt;waitingForUser&lt;&#x2F;code&gt;. Then, a mutual authentication process is carried out with the user, as already done with the owner. The user sends the transaction associated with the function &lt;code&gt;startUserEngagement&lt;&#x2F;code&gt;. As in &lt;code&gt;startOwnerEngagement&lt;&#x2F;code&gt;, this function saves the public key generated by the user, PK&lt;sub&gt;U_A&lt;&#x2F;sub&gt;, as the attribute &lt;code&gt;dataEngagement&lt;&#x2F;code&gt; and the hash of K&lt;sub&gt;U&lt;&#x2F;sub&gt; = PK&lt;sub&gt;A&lt;&#x2F;sub&gt; * SK&lt;sub&gt;U_A&lt;&#x2F;sub&gt; as the attribute &lt;code&gt;hashK_UA&lt;&#x2F;code&gt; in the NFT.&lt;&#x2F;p&gt;
&lt;p&gt;The user sends request engagement and the asset calculates:&lt;&#x2F;p&gt;
&lt;p&gt;K&lt;sub&gt;A&lt;&#x2F;sub&gt; = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * PK&lt;sub&gt;U_A&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If everything is correctly done, K&lt;sub&gt;U&lt;&#x2F;sub&gt; and K&lt;sub&gt;A&lt;&#x2F;sub&gt; are the same since:&lt;&#x2F;p&gt;
&lt;p&gt;K&lt;sub&gt;U&lt;&#x2F;sub&gt; = PK&lt;sub&gt;A&lt;&#x2F;sub&gt; * SK&lt;sub&gt;U_A&lt;&#x2F;sub&gt; = (SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * P) * SK&lt;sub&gt;U_A&lt;&#x2F;sub&gt; = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * (SK&lt;sub&gt;U_A&lt;&#x2F;sub&gt; * P) = SK&lt;sub&gt;A&lt;&#x2F;sub&gt; * PK&lt;sub&gt;U_A&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the function &lt;code&gt;userEngagement&lt;&#x2F;code&gt;, the asset sends the hash of K&lt;sub&gt;A&lt;&#x2F;sub&gt; obtained and if it is the same as the data in &lt;code&gt;hashK_UA&lt;&#x2F;code&gt;, then the state of the token changes to &lt;code&gt;engagedWithUser&lt;&#x2F;code&gt; and the event &lt;code&gt;UserEngaged&lt;&#x2F;code&gt; is sent. Once the asset receives the event, it changes its operation mode to &lt;code&gt;engagedWithUser&lt;&#x2F;code&gt;. This process is shown in &lt;code&gt;Figure 5&lt;&#x2F;code&gt;. From this moment, the asset can be managed by the user and they can communicate in a secure way using the shared key.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;images&#x2F;Figure5.jpg&quot; alt=&quot;Figure 5: Steps in a successful user and asset mutual authentication process&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since the establishment of a shared secret key is very important for a secure communication, NFTs include the attributes
&lt;code&gt;hashK_OA&lt;&#x2F;code&gt;, &lt;code&gt;hashK_UA&lt;&#x2F;code&gt; and &lt;code&gt;dataEngagement&lt;&#x2F;code&gt;. The first two attributes define, respectively, the hash of the secret key shared between the asset and its owner and between the asset and its user. Assets, owners and users should check they are using the correct shared secret keys. The attribute &lt;code&gt;dataEngagement&lt;&#x2F;code&gt; defines the public data needed for the agreement.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-4519 NFT: Extension of EIP-721 Non-Fungible Token Standard. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the EIP-165 identifier for this interface is 0x8a68abe3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EIP&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4519&lt;&#x2F;span&gt;&lt;span&gt; NFT is EIP721&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;,EIP165&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when the NFT is assigned as utility of a new user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  This event emits when the user of the token changes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  (`_addressUser` == 0) when no user is assigned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UserAssigned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when user and asset finish mutual authentication process successfully.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  This event emits when both the user and the asset prove they share a secure communication channel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UserEngaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when owner and asset finish mutual authentication process successfully.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  This event emits when both the owner and the asset prove they share a secure communication channel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OwnerEngaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when it is checked that the timeout has expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  This event emits when the timestamp of the EIP-4519 NFT is not updated in timeout.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TimeoutAlarm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function defines how the NFT is assigned as utility of a new user (if &amp;quot;addressUser&amp;quot; is defined).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the owner of the EIP-4519 NFT can assign a user. If &amp;quot;addressAsset&amp;quot; is defined, then the state of the token must be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;engagedWithOwner&amp;quot;,&amp;quot;waitingForUser&amp;quot; or &amp;quot;engagedWithUser&amp;quot; and this function changes the state of the token defined by &amp;quot;_tokenId&amp;quot; to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;waitingForUser&amp;quot;. If &amp;quot;addressAsset&amp;quot; is not defined, the state is set to &amp;quot;userAssigned&amp;quot;. In both cases, this function sets the parameter &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;addressUser&amp;quot; to &amp;quot;_addressUser&amp;quot;. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the new user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setUser&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function defines the initialization of the mutual authentication process between the owner and the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the owner of the token can start this authentication process if &amp;quot;addressAsset&amp;quot; is defined and the state of the token is &amp;quot;waitingForOwner&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The function does not change the state of the token and saves &amp;quot;_dataEngagement&amp;quot; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; and &amp;quot;_hashK_OA&amp;quot; in the parameters of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _dataEngagement&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the public data proposed by the owner for the agreement of the shared key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hashK_OA&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the hash of the secret proposed by the owner to share with the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; startOwnerEngagement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _dataEngagement&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hashK_OA&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function completes the mutual authentication process between the owner and the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the asset tied to the token can finish this authentication process provided that the state of the token is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;waitingForOwner&amp;quot; and dataEngagement is different from 0. This function compares hashK_OA saved in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the token with hashK_A. If they are equal then the state of the token changes to &amp;quot;engagedWithOwner&amp;quot;, dataEngagement is set to 0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; and the event &amp;quot;OwnerEngaged&amp;quot; is emitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hashK_A&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the hash of the secret generated by the asset to share with the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerEngagement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hashK_A&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function defines the initialization of the mutual authentication process between the user and the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the user of the token can start this authentication process if &amp;quot;addressAsset&amp;quot; and &amp;quot;addressUser&amp;quot; are defined and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the state of the token is &amp;quot;waitingForUser&amp;quot;. The function does not change the state of the token and saves &amp;quot;_dataEngagement&amp;quot; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; and &amp;quot;_hashK_UA&amp;quot; in the parameters of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _dataEngagement&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the public data proposed by the user for the agreement of the shared key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hashK_UA&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the hash of the secret proposed by the user to share with the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; startUserEngagement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _dataEngagement&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hashK_UA&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function completes the mutual authentication process between the user and the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the asset tied to the token can finish this authentication process provided that the state of the token is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;waitingForUser&amp;quot; and dataEngagement is different from 0. This function compares hashK_UA saved in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the token with hashK_A. If they are equal then the state of the token changes to &amp;quot;engagedWithUser&amp;quot;, dataEngagement is set to 0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; and the event &amp;quot;UserEngaged&amp;quot; is emitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hashK_A&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the hash of the secret generated by the asset to share with the user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userEngagement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hashK_A&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span&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&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function checks if the timeout has expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function to check if the timeout has expired. The event &amp;quot;TimeoutAlarm&amp;quot; is emitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if the timeout has expired.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if timeout has expired and false in other case.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkTimeout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function sets the value of timeout.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the owner of the token can set this value provided that the state of the token is &amp;quot;engagedWithOwner&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;quot;waitingForUser&amp;quot; or &amp;quot;engagedWithUser&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _timeout&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the value to assign to timeout.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTimeout&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _timeout&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function updates the timestamp, thus avoiding the timeout alarm.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the asset tied to the token can update its own timestamp.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateTimestamp&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets obtain the tokenId from an address. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address to obtain the tokenId from it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the token tied to the asset that generates _addressAsset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenFromBCA&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets know the owner of the token from the address of the asset tied to the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address to obtain the owner from it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the token bound to the asset that generates _addressAsset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOfFromBCA&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets know the user of the token from its tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the tokenId of the EIP-4519 NFT tied to the asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the token from its _tokenId.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets know the user of the token from the address of the asset tied to the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address to obtain the user from it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; user&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the token tied to the asset that generates _addressAsset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userOfFromBCA&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressAsset&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets know how many tokens are assigned to a user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; number&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of tokens assigned to a user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userBalanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function lets know how many tokens of a particular owner are assigned to a user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Everybody can call this function. The code executed only reads from Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the user.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addressOwner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; number&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of tokens assigned to a user from an owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; userBalanceOfAnOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressUser&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addressOwner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;authentication&quot;&gt;Authentication&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP uses smart contracts to verify the mutual authentication process since smart contracts are trustless.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tie-time&quot;&gt;Tie Time&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP proposes including the attribute timestamp (to register in Ethereum the last time that the physical asset checked the tie with its token) and the attribute timeout (to register the maximum delay time established for the physical asset to prove again the tie). These attributes avoid that a malicious owner or user could use the asset endlessly.&lt;&#x2F;p&gt;
&lt;p&gt;When the asset calls &lt;code&gt;updateTimestamp&lt;&#x2F;code&gt;, the smart contract must call &lt;code&gt;block.timestamp&lt;&#x2F;code&gt;, which provides current block timestamp as seconds since Unix epoch. For this reason, &lt;code&gt;timeout&lt;&#x2F;code&gt;  must be provided in seconds.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eip-721-based&quot;&gt;EIP-721-based&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; is the most commonly-used standard for generic NFTs. This EIP extends EIP-721 for backwards compatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is an extension of EIP-721. It is fully compatible with both of the commonly used optional extensions (&lt;code&gt;IERC721Metadata&lt;&#x2F;code&gt; and &lt;code&gt;IERC721Enumerable&lt;&#x2F;code&gt;) mentioned in the EIP-721 standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The test cases presented in the paper shown below are available &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;assets&#x2F;PoC_SmartNFT&#x2F;README&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A first version was presented in a paper of the Special Issue &lt;strong&gt;Security, Trust and Privacy in New Computing Environments&lt;&#x2F;strong&gt; of &lt;strong&gt;Sensors&lt;&#x2F;strong&gt; journal of &lt;strong&gt;MDPI&lt;&#x2F;strong&gt; editorial. The paper, entitled &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4519&#x2F;.&#x2F;assets&#x2F;sensors-21-03119.pdf&quot;&gt;Secure Combination of IoT and Blockchain by Physically Binding IoT Devices to Smart Non-Fungible Tokens Using PUFs&lt;&#x2F;a&gt;, was written by the same authors of this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;In this EIP, a generic system has been proposed for the creation of non-fungible tokens tied to physical assets. A generic point of view based on the improvements of the current EIP-721 NFT is provided, such as the implementation of the user management mechanism, which does not affect the token&#x27;s ownership. The physical asset should have the ability to generate an Ethereum address from itself in a totally random way so that only the asset is able to know the secret from which the Ethereum address is generated. In this way, identity theft is avoided and the asset can be proven to be completely genuine. In order to ensure this, it is recommended that only the manufacturer of the asset has the ability to create its associated token. In the case of an IoT device, the device firmware will be unable to share and modify the secret. Instead of storing the secrets, it is recommended that assets reconstruct their secrets from non-sensitive information such as the helper data associated with Physical Unclonable Functions (PUFs). Although a secure key exchange protocol based on elliptic curves has been proposed, the token is open to coexist with other types of key exchange.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Supplant DIFFICULTY opcode with PREVRANDAO</title>
        <published>2021-10-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mikhail Kalinin</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4399/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4399-supplant-difficulty-opcode-with-random/7368" />
        

        <id>https://wg-eips.ritovision.com/4399/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:4399"
            label="EIP-4399" />
        

        
        

        
        <summary type="html">Expose beacon chain randomness in the EVM by supplanting DIFFICULTY opcode semantics</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4399/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP supplants the semantics of the return value of existing &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; opcode and renames the opcode to &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The return value of the &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; instruction after this change is the output of the randomness beacon provided by the beacon chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Applications may benefit from using the randomness accumulated by the beacon chain. Thus, randomness outputs produced by the beacon chain should be accessible in the EVM.&lt;&#x2F;p&gt;
&lt;p&gt;At the point of &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; of the Proof-of-Stake (PoS) upgrade described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt;, the &lt;code&gt;difficulty&lt;&#x2F;code&gt; block field &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be &lt;code&gt;0&lt;&#x2F;code&gt; thereafter because there is no longer any Proof-of-Work (PoW) seal on the block. This means that the &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; instruction no longer has it&#x27;s previous semantic meaning, nor a clear &quot;correct&quot; value to return.&lt;&#x2F;p&gt;
&lt;p&gt;Given prior analysis on the usage of &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt;, the value returned by the instruction mixed with other values is a common pattern used by smart contracts to obtain randomness. The instruction with the same number as the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; opcode returning outputs of the beacon chain RANDAO implementation makes the upgrade to PoS backwards compatible for existing smart contracts obtaining randomness from the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; instruction.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, changes proposed by this EIP allow for smart contracts to determine whether the upgrade to the PoS has already happened. This can be done by analyzing the return value of the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; instruction. A value greater than &lt;code&gt;2**64&lt;&#x2F;code&gt; indicates that the transaction is being executed in the PoS block. Decompilers and other similar tooling may also use this trick to discern the new semantics of the instruction if data of the block including the transaction in question is available.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The definition of this block can be found in the Definitions section of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#definitions&quot;&gt;EIP-3675&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;block-structure&quot;&gt;Block structure&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, client software &lt;strong&gt;MUST&lt;&#x2F;strong&gt; set the value of the &lt;code&gt;mixHash&lt;&#x2F;code&gt;, i.e. the field with the number &lt;code&gt;13&lt;&#x2F;code&gt; (0-indexed) in a block header, to the latest RANDAO mix of the post beacon state of the previous block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;evm&quot;&gt;EVM&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, the &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; instruction &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the value of the &lt;code&gt;mixHash&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: The gas cost of the &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; opcode remains unchanged.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;renaming&quot;&gt;Renaming&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mixHash&lt;&#x2F;code&gt; field &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; further be renamed to &lt;code&gt;prevRandao&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; opcode &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; further be renamed to &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;including-randao-output-in-the-block-header&quot;&gt;Including RANDAO output in the block header&lt;&#x2F;h3&gt;
&lt;p&gt;Including a RANDAO output in the block header provides a straightforward method of accessing it from inside of the EVM as block header data is already available in the EVM context.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, this ensures that the execution layer can be fully executed with the block alone rather than requiring extra inputs from the PoS consensus layer.&lt;&#x2F;p&gt;
&lt;p&gt;Mixing the randomness into a block header may contribute to uniqueness of the block hash in the case when values of other fields of the block header match the corresponding values of the header of another block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-mixhash-field-instead-of-difficulty&quot;&gt;Using &lt;code&gt;mixHash&lt;&#x2F;code&gt; field instead of &lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mixHash&lt;&#x2F;code&gt; header field is used instead of &lt;code&gt;difficulty&lt;&#x2F;code&gt; to avoid a class of hidden forkchoice bugs after the PoS upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;Client software implementing pre-EIP-3675 logic heavily depends on the &lt;code&gt;difficulty&lt;&#x2F;code&gt; value as total difficulty computation is the basis of the PoW fork choice rule. Setting the &lt;code&gt;difficulty&lt;&#x2F;code&gt; field to &lt;code&gt;0&lt;&#x2F;code&gt; at the PoS upgrade aims to reduce the surface of bugs related to the total difficulty value growing after the upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, any latent total difficulty computation after the PoS upgrade would become overflow prone if the randomness output supplanted the value of the &lt;code&gt;difficulty&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reusing-existing-field-instead-of-appending-a-new-one&quot;&gt;Reusing existing field instead of appending a new one&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;mixHash&lt;&#x2F;code&gt; field is deprecated at the PoS upgrade and set to zero bytes array thereafter. Reusing an existing field as a place for the randomness output saves 32 bytes per block and effectively removes the deprecation of one of the fields induced by the upgrade.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reusing-the-difficulty-opcode-instead-of-introducing-a-new-one&quot;&gt;Reusing the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; opcode instead of introducing a new one&lt;&#x2F;h3&gt;
&lt;p&gt;See the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4399&#x2F;#motivation&quot;&gt;Motivation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;renaming-the-field-and-the-opcode&quot;&gt;Renaming the field and the opcode&lt;&#x2F;h3&gt;
&lt;p&gt;The renaming should be done to make the field and the opcode names semantically sound.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-transition-block-rather-than-a-block-or-slot-number&quot;&gt;Using &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; rather than a block or slot number&lt;&#x2F;h3&gt;
&lt;p&gt;By utilizing &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; to trigger the change in logic defined in this EIP rather than a block or slot number, this EIP is tightly coupled to the PoS upgrade defined by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By tightly coupling to the PoS upgrade, we ensure that there is no discontinuity for the usecase of this opcode for randomness -- the primary &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4399&#x2F;#motivation&quot;&gt;motivation&lt;&#x2F;a&gt; for re-using &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; rather than creating a new opcode.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-2-64-threshold-to-determine-pos-blocks&quot;&gt;Using &lt;code&gt;2**64&lt;&#x2F;code&gt; threshold to determine PoS blocks&lt;&#x2F;h3&gt;
&lt;p&gt;The probability of RANDAO value to fall into the range between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;2**64&lt;&#x2F;code&gt; and, thus, to be mixed with PoW difficulty values, is drastically low. Though, proposed threshold might seem to have insufficient distance from difficulty values on Ethereum Mainnet (they are currently around &lt;code&gt;2**54&lt;&#x2F;code&gt;), it requires a thousand times increase of the hashrate to make this threshold insecure. Such an increase is considered impossible to occur before the upcoming consensus upgrade.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backward incompatible changes to the execution and validation of EVM state transitions. As written, this EIP utilizes &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; and is thus tightly coupled with the PoS upgrade introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;&quot;&gt;EIP-3675&lt;&#x2F;a&gt;. If this EIP is to be adopted, it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be scheduled at the same time as EIP-3675.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the changes proposed might be backward incompatible for the following categories of applications:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Applications that use the value returned by the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; opcode as the PoW &lt;code&gt;difficulty&lt;&#x2F;code&gt; parameter&lt;&#x2F;li&gt;
&lt;li&gt;Applications with logic that depends on the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; opcode returning a relatively small number with respect to the full 256-bit size of the field.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first category is already affected by switching the consensus mechanism to PoS and no additional breaking changes are introduced by this specification.&lt;&#x2F;p&gt;
&lt;p&gt;The second category is comprised of applications that use the return value of the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; opcode in operations that might cause either overflow or underflow errors. While it is theoretically possible to author an application where a change in the range of possible values this opcode may return could lead to a security vulnerability, the chances of that are negligible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;In one of ancestors of &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; deploy a contract that stores return value of  &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; to the state&lt;&#x2F;li&gt;
&lt;li&gt;Check that value returned by &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; in transaction executed within the parent of &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; equals &lt;code&gt;difficulty&lt;&#x2F;code&gt; field value&lt;&#x2F;li&gt;
&lt;li&gt;Check that value returned by &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt; in transaction executed within &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; equals &lt;code&gt;prevRandao&lt;&#x2F;code&gt; field value&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt; opcode in PoS Ethereum (based on the beacon chain RANDAO implementation) is a source of randomness with different properties to the randomness supplied by &lt;code&gt;BLOCKHASH (0x40)&lt;&#x2F;code&gt; or &lt;code&gt;DIFFICULTY (0x44)&lt;&#x2F;code&gt; opcodes in the PoW network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;biasability&quot;&gt;Biasability&lt;&#x2F;h3&gt;
&lt;p&gt;The beacon chain RANDAO implementation gives every block proposer 1 bit of influence power per slot. Proposer may deliberately refuse to propose a block on the opportunity cost of proposer and transaction fees to prevent beacon chain randomness (a RANDAO mix) from being updated in a particular slot.&lt;&#x2F;p&gt;
&lt;p&gt;An effect of proposer&#x27;s influence power is limited in time and lasts until the first honest RANDAO reveal is made afterwards. This limitation does also exist in the case when proposers of &lt;code&gt;n&lt;&#x2F;code&gt; consecutive slots are colluding to get &lt;code&gt;n&lt;&#x2F;code&gt; bits of influence power. Simply speaking, one honest block proposal is enough to unbias the RANDAO even if it was biased during several slots in a row.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, semantics of the &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt; instruction gives proposers another way to gain 1 bit of influence power on applications. Biased proposer may censor a rolling the dice transaction to force it to be included into the next block, thus, force it to use a RANDAO mix that the proposer knows in advance. The opportunity cost in this case would be negligible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;predictability&quot;&gt;Predictability&lt;&#x2F;h3&gt;
&lt;p&gt;Obviously, historical randomness provided by any decentralized oracle is 100% predictable. On the contrary, the randomness that is revealed in the future is predictable up to a limited extent.&lt;&#x2F;p&gt;
&lt;p&gt;A list of inputs influencing future randomness on the beacon chain consists of but is not limited to the following items:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Accumulated randomness.&lt;&#x2F;strong&gt; A RANDAO mix produced by the beacon chain in the last slot of epoch &lt;code&gt;N&lt;&#x2F;code&gt; is the main input to the function defining block proposers in each slot of epoch &lt;code&gt;N + MIN_SEED_LOOKAHEAD + 1&lt;&#x2F;code&gt;, i.e. it is the main factor defining future RANDAO revealers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Number of active validators.&lt;&#x2F;strong&gt; A number of active validators throughout an epoch is another input to the block proposer function.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Effective balance.&lt;&#x2F;strong&gt; All else being equal, the lower the effective balance of a validator the lower the chance this validator has to be designated as a proposer in a slot.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Accidentally missed proposals.&lt;&#x2F;strong&gt; Network conditions and other factors that are resulting in accidentally missed proposals is a source of highly qualitative entropy that impacts RANDAO mixes. Usual rate of missed proposals on the Mainnet is about &lt;code&gt;1%&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These inputs may be predictable and malleable on a short range of slots but the longer the attempted lookahead the more entropy is accumulated by the beacon chain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tips-for-application-developers&quot;&gt;Tips for application developers&lt;&#x2F;h3&gt;
&lt;p&gt;The following tips attempt to reduce predictability and biasability of randomness outputs returned by &lt;code&gt;PREVRANDAO (0x44)&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Make your applications rely on the future randomness with a reasonably high lookahead. For example, an application stops accepting bids at the end of epoch &lt;code&gt;K&lt;&#x2F;code&gt; and uses a RANDAO mix produced in slot &lt;code&gt;K + N + ε&lt;&#x2F;code&gt; to roll the dice, where &lt;code&gt;N&lt;&#x2F;code&gt; is a lookahead in epochs and &lt;code&gt;ε&lt;&#x2F;code&gt; is a few slots into epoch &lt;code&gt;N + 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;At least four epochs of lookahead results in the following outcome:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;A proposer set of epoch &lt;code&gt;N + 1&lt;&#x2F;code&gt; isn&#x27;t known at the end of epoch &lt;code&gt;K&lt;&#x2F;code&gt; breaking a direct link between bidders and dice rollers&lt;&#x2F;li&gt;
&lt;li&gt;A number of active validators is updated at the end of each epoch affecting a set of proposers of next epochs, thus, impacting a RANDAO mix used by the application to roll the dice&lt;&#x2F;li&gt;
&lt;li&gt;Due to Mainnet statistics, there is about a &lt;code&gt;100%&lt;&#x2F;code&gt; chance for the network to accidentally miss a proposal during this period of time which reduces predictability of a RANDAO mix used to roll the dice.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Setting &lt;code&gt;ε&lt;&#x2F;code&gt; to a small number, e.g. 2 or 4 slots, gives a third party a little time to gain influence power on the future randomness that is being used to roll the dice. This amount of time is defined by &lt;code&gt;MIN_SEED_LOOKAHEAD&lt;&#x2F;code&gt; parameter and is about 6 minutes on the Mainnet.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A reasonably high distance between bidding and rolling the dice attempts to leave low chance for bidders controlling a subset of validators to directly exploit their influence power. Ultimately, this chance depends on the type of the game and on a number of controlled validators. For instance, a chance of a single validator to affect a one-time game is negligible, and becomes bigger for multiple validators in a repeated game scenario.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>EIP-721 Consumable Extension</title>
        <published>2021-10-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Daniel Ivanov</name><uri>https://github.com/Daniel-K-Ivanov</uri>
	</author>
	
	<author>
		<name>George Spasov</name><uri>https://github.com/Perseverance</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4400/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/EIP-4400-EIP721consumer-extension/7371" />
        

        <id>https://wg-eips.ritovision.com/4400/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4400"
            label="ERC-4400" />
        

        
        

        
        <summary type="html">Interface extension for EIP-721 consumer role</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4400/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines standard functions outlining a &lt;code&gt;consumer&lt;&#x2F;code&gt; role for instance(s) of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;. An implementation allows reading the current &lt;code&gt;consumer&lt;&#x2F;code&gt; for a given NFT (&lt;code&gt;tokenId&lt;&#x2F;code&gt;) along with a standardized event for when an &lt;code&gt;consumer&lt;&#x2F;code&gt; has changed. The proposal depends on and extends the existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; contracts introduce their own custom role that grants permissions for utilising&#x2F;consuming a given NFT instance. The need for that role stems from the fact that other than owning the NFT instance, there are other actions that can be performed on an NFT. For example, various metaverses use &lt;code&gt;operator&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;contributor&lt;&#x2F;code&gt; roles for Land (EIP-721), so that owners of the land can authorise other addresses to deploy scenes to them (f.e. commissioning a service company to develop a scene).&lt;&#x2F;p&gt;
&lt;p&gt;It is common for NFTs to have utility other than ownership. That being said, it requires a separate standardized consumer role, allowing compatibility with user interfaces and contracts, managing those contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Having a &lt;code&gt;consumer&lt;&#x2F;code&gt; role will enable protocols to integrate and build on top of dApps that issue EIP-721 tokens. One example is the creation of generic&#x2F;universal NFT renting marketplaces.&lt;&#x2F;p&gt;
&lt;p&gt;Example of kinds of contracts and applications that can benefit from this standard are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;metaverses that have land and other types of digital assets in those metaverses (scene deployment on land, renting land &#x2F; characters &#x2F; clothes &#x2F; passes to events etc.)&lt;&#x2F;li&gt;
&lt;li&gt;NFT-based yield-farming. Adopting the standard enables the &quot;staker&quot; (owner of the NFT) to have access to the utility benefits even after transferring his NFT to the staking contract&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;Every contract compliant to the &lt;code&gt;EIP721Consumable&lt;&#x2F;code&gt; extension MUST implement the &lt;code&gt;IEIP721Consumable&lt;&#x2F;code&gt; interface. The &lt;strong&gt;consumer extension&lt;&#x2F;strong&gt; is OPTIONAL for EIP-721 contracts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-721 Consumer Role extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the EIP-165 identifier for this interface is 0x953c8dfa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IEIP721Consumable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is EIP721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when `owner` changes the `consumer` of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address for consumer indicates that there is no consumer address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; When a Transfer event emits, this also indicates that the consumer address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; for that NFT (if any) is set to none&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ConsumerChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; consumer&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the consumer address of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates that there is no consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_tokenId` is not a valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to get the consumer address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; consumer address for this NFT, or the zero address if there is none&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; consumerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Change or reaffirm the consumer address for an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no consumer address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws unless `msg.sender` is the current NFT owner, an authorised&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; operator of the current owner or approved address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_tokenId` is not valid NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new consumer of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; changeConsumer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every contract implementing the &lt;code&gt;EIP721Consumable&lt;&#x2F;code&gt; extension is free to define the permissions of a &lt;code&gt;consumer&lt;&#x2F;code&gt; (e.g. what are consumers allowed to do within their system) with only one exception - consumers MUST NOT be considered owners, authorised operators or approved addresses as per the EIP-721 specification. Thus, they MUST NOT be able to execute transfers &amp;amp; approvals.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;consumerOf(uint256 _tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;changeConsumer(address _consumer, uint256 _tokenId)&lt;&#x2F;code&gt; function MAY be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ConsumerChanged&lt;&#x2F;code&gt; event MUST be emitted when a consumer is changed.&lt;&#x2F;p&gt;
&lt;p&gt;On every &lt;code&gt;transfer&lt;&#x2F;code&gt;, the consumer MUST be changed to a default address. It is RECOMMENDED for implementors to use &lt;code&gt;address(0)&lt;&#x2F;code&gt; as that default address.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; method MUST return &lt;code&gt;true&lt;&#x2F;code&gt; when called with &lt;code&gt;0x953c8dfa&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Key factors influencing the standard:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Keeping the number of functions in the interfaces to a minimum to prevent contract bloat&lt;&#x2F;li&gt;
&lt;li&gt;Simplicity&lt;&#x2F;li&gt;
&lt;li&gt;Gas Efficiency&lt;&#x2F;li&gt;
&lt;li&gt;Not reusing or overloading other already existing roles (e.g. owners, operators, approved addresses)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;name&quot;&gt;Name&lt;&#x2F;h3&gt;
&lt;p&gt;The chosen name resonates with the purpose of its existence. Consumers can be considered entities that utilise the token instances, without necessarily having ownership rights to it.&lt;&#x2F;p&gt;
&lt;p&gt;The other name for the role that was considered was &lt;code&gt;operator&lt;&#x2F;code&gt;, however it is already defined and used within the &lt;code&gt;EIP-721&lt;&#x2F;code&gt; standard.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;restriction-on-the-permissions&quot;&gt;Restriction on the Permissions&lt;&#x2F;h3&gt;
&lt;p&gt;There are numerous use-cases where a distinct role for NFTs is required that MUST NOT have owner permissions. A contract that implements the consumer role and grants ownership permissions to the consumer renders this standard pointless.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with current EIP-721 standards. There are no other standards that define a similar role for NFTs and the name (&lt;code&gt;consumer&lt;&#x2F;code&gt;) is not used by other EIP-721 related standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases are available in the reference implementation &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4400&#x2F;.&#x2F;assets&#x2F;test&#x2F;erc721-consumable.ts&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The reference implementation can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4400&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC721Consumable.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Implementors of the &lt;code&gt;EIP721Consumable&lt;&#x2F;code&gt; standard must consider thoroughly the permissions they give to &lt;code&gt;consumers&lt;&#x2F;code&gt;. Even if they implement the standard correctly and do not allow transfer&#x2F;burning of NFTs, they might still provide permissions to the &lt;code&gt;consumers&lt;&#x2F;code&gt; that they might not want to provide otherwise and should be restricted to &lt;code&gt;owners&lt;&#x2F;code&gt; only.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Sign-In with Ethereum</title>
        <published>2021-10-11T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Wayne Chang</name><uri>https://github.com/wyc</uri>
	</author>
	
	<author>
		<name>Gregory Rocco</name><uri>https://github.com/obstropolos</uri>
	</author>
	
	<author>
		<name>Brantly Millegan</name><uri>https://github.com/brantlymillegan</uri>
	</author>
	
	<author>
		<name>Nick Johnson</name><uri>https://github.com/Arachnid</uri>
	</author>
	
	<author>
		<name>Oliver Terbu</name><uri>https://github.com/awoie</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4361/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4361-sign-in-with-ethereum/7263" />
        

        <id>https://wg-eips.ritovision.com/4361/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:4361"
            label="ERC-4361" />
        

        
        

        
        <summary type="html">Off-chain authentication for Ethereum accounts to establish sessions.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4361/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Sign-In with Ethereum describes how Ethereum accounts authenticate with off-chain services by signing a standard message format parameterized by scope, session details, and security mechanisms (e.g., a nonce). The goals of this specification are to provide a self-custodied alternative to centralized identity providers, improve interoperability across off-chain services for Ethereum-based authentication, and provide wallet vendors a consistent machine-readable message format to achieve improved user experiences and consent management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;When signing in to popular non-blockchain services today, users will typically use identity providers (IdPs) that are centralized entities with ultimate control over users&#x27; identifiers, for example, large internet companies and email providers. Incentives are often misaligned between these parties. Sign-In with Ethereum offers a new self-custodial option for users who wish to assume more control and responsibility over their own digital identity.&lt;&#x2F;p&gt;
&lt;p&gt;Already, many services support workflows to authenticate Ethereum accounts using message signing, such as to establish a cookie-based web session which can manage privileged metadata about the authenticating address. This is an opportunity to standardize the sign-in workflow and improve interoperability across existing services, while also providing wallet vendors a reliable method to identify signing requests as Sign-In with Ethereum requests for improved UX.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;Sign-In with Ethereum (SIWE) works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The relying party generates a SIWE Message and prefixes the SIWE Message with &lt;code&gt;\x19Ethereum Signed Message:\n&amp;lt;length of message&amp;gt;&lt;&#x2F;code&gt; as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The wallet presents the user with a structured plaintext message or equivalent interface for signing the SIWE Message with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; signed data format.&lt;&#x2F;li&gt;
&lt;li&gt;The signature is then presented to the relying party, which checks the signature&#x27;s validity and SIWE Message content.&lt;&#x2F;li&gt;
&lt;li&gt;The relying party might further fetch data associated with the Ethereum address, such as from the Ethereum blockchain (e.g., ENS, account balances, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; asset ownership), or other data sources that might or might not be permissioned.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;message-format&quot;&gt;Message Format&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;abnf-message-format&quot;&gt;ABNF Message Format&lt;&#x2F;h4&gt;
&lt;p&gt;A SIWE Message MUST conform with the following Augmented Backus–Naur Form (ABNF, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc5234&quot;&gt;RFC 5234&lt;&#x2F;a&gt;) expression (note that &lt;code&gt;%s&lt;&#x2F;code&gt; denotes case sensitivity for a string term, as per &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc7405&quot;&gt;RFC 7405&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;ABNF&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sign-in-with-ethereum =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; scheme&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; wants you to sign in with your Ethereum account:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; statement&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;URI: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uri&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Version: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Chain ID: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; chain-id&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Nonce: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Issued At: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; issued-at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Expiration Time: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; expiration-time&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not Before: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; not-before&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Request ID: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; request-id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Resources:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&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&gt;scheme =&lt;&#x2F;span&gt;&lt;span&gt; ALPHA&lt;&#x2F;span&gt;&lt;span&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt; ALPHA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; DIGIT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3986 for the fully contextualized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; definition of &amp;quot;scheme&amp;quot;.&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;domain =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; authority&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; From RFC 3986:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     authority     = [ userinfo &amp;quot;@&amp;quot; ] host [ &amp;quot;:&amp;quot; port ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3986 for the fully contextualized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; definition of &amp;quot;authority&amp;quot;.&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;address =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; 40*40&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;HEXDIG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Must also conform to capitalization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; checksum encoding specified in EIP-55&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; where applicable (EOAs).&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;statement =&lt;&#x2F;span&gt;&lt;span&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; reserved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; unreserved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3986 for the definition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of &amp;quot;reserved&amp;quot; and &amp;quot;unreserved&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The purpose is to exclude LF (line break).&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;uri =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3986 for the definition of &amp;quot;URI&amp;quot;.&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;version =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&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;chain-id =&lt;&#x2F;span&gt;&lt;span&gt; 1*&lt;&#x2F;span&gt;&lt;span&gt;DIGIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See EIP-155 for valid CHAIN_IDs.&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;nonce =&lt;&#x2F;span&gt;&lt;span&gt; 8*&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt; ALPHA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; DIGIT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 5234 for the definition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of &amp;quot;ALPHA&amp;quot; and &amp;quot;DIGIT&amp;quot;.&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;issued-at =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; date-time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;expiration-time =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; date-time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;not-before =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; date-time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3339 (ISO 8601) for the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; definition of &amp;quot;date-time&amp;quot;.&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;request-id =&lt;&#x2F;span&gt;&lt;span&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;pchar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See RFC 3986 for the definition of &amp;quot;pchar&amp;quot;.&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;resources =&lt;&#x2F;span&gt;&lt;span&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt; LF&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&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&gt;resource =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;- &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;message-fields&quot;&gt;Message Fields&lt;&#x2F;h4&gt;
&lt;p&gt;This specification defines the following SIWE Message fields that can be parsed from a SIWE Message by following the rules in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#abnf-message-format&quot;&gt;ABNF Message Format&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scheme&lt;&#x2F;code&gt; OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;domain&lt;&#x2F;code&gt; REQUIRED. The domain that is requesting the signing. Its value MUST be an RFC 3986 authority. The authority includes an OPTIONAL port. If the port is not specified, the default port for the provided &lt;code&gt;scheme&lt;&#x2F;code&gt; is assumed (e.g., 443 for HTTPS). If &lt;code&gt;scheme&lt;&#x2F;code&gt; is not specified, HTTPS is assumed by default.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;address&lt;&#x2F;code&gt; REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;55&#x2F;&quot;&gt;ERC-55&lt;&#x2F;a&gt; where applicable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;statement&lt;&#x2F;code&gt; OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include &lt;code&gt;&#x27;\n&#x27;&lt;&#x2F;code&gt; (the byte &lt;code&gt;0x0a&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;uri&lt;&#x2F;code&gt; REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the &lt;em&gt;subject of a claim&lt;&#x2F;em&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;version&lt;&#x2F;code&gt; REQUIRED. The current version of the SIWE Message, which MUST be &lt;code&gt;1&lt;&#x2F;code&gt; for this specification.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;chain-id&lt;&#x2F;code&gt; REQUIRED. The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;nonce&lt;&#x2F;code&gt; REQUIRED. A random string typically chosen by the relying party and used to prevent replay attacks, at least 8 alphanumeric characters.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;issued-at&lt;&#x2F;code&gt; REQUIRED. The time when the message was generated, typically the current time. Its value MUST be an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3339&quot;&gt;RFC 3339&lt;&#x2F;a&gt; datetime string.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;expiration-time&lt;&#x2F;code&gt; OPTIONAL. The time when the signed authentication message is no longer valid. Its value MUST be an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3339&quot;&gt;RFC 3339&lt;&#x2F;a&gt; datetime string.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;not-before&lt;&#x2F;code&gt; OPTIONAL. The time when the signed authentication message will become valid. Its value MUST be an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3339&quot;&gt;RFC 3339&lt;&#x2F;a&gt; datetime string.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;request-id&lt;&#x2F;code&gt; OPTIONAL. A system-specific identifier that MAY be used to uniquely refer to the sign-in request.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resources&lt;&#x2F;code&gt; OPTIONAL. A list of information or references to information the user wishes to have resolved as part of authentication by the relying party. Every resource MUST be an RFC 3986 URI separated by &lt;code&gt;&quot;\n- &quot;&lt;&#x2F;code&gt; where &lt;code&gt;\n&lt;&#x2F;code&gt; is the byte &lt;code&gt;0x0a&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;informal-message-template&quot;&gt;Informal Message Template&lt;&#x2F;h4&gt;
&lt;p&gt;A Bash-like informal template of the full SIWE Message is presented below for readability and ease of understanding, and it does not reflect the allowed optionality of the fields. Field descriptions are provided in the following section. A full ABNF description is provided in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#abnf-message-format&quot;&gt;ABNF Message Format&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;${scheme}:&#x2F;&#x2F; ${domain} wants you to sign in with your Ethereum account:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;${address}&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;${statement}&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;URI: ${uri}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version: ${version}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Chain ID: ${chain-id}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce: ${nonce}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Issued At: ${issued-at}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Expiration Time: ${expiration-time}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Not Before: ${not-before}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Request ID: ${request-id}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- ${resources[0]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- ${resources[1]}&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;- ${resources[n]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h4&gt;
&lt;p&gt;The following is an example SIWE Message with an implicit scheme:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;example.com wants you to sign in with your Ethereum account:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&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;I accept the ExampleOrg Terms of Service: https:&#x2F;&#x2F;example.com&#x2F;tos&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;URI: https:&#x2F;&#x2F;example.com&#x2F;login&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Chain ID: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce: 32891756&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Issued At: 2021-09-30T16:25:24Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- ipfs:&#x2F;&#x2F;bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- https:&#x2F;&#x2F;example.com&#x2F;my-web2-claim.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The following is an example SIWE Message with an implicit scheme and explicit port:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;example.com:3388 wants you to sign in with your Ethereum account:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&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;I accept the ExampleOrg Terms of Service: https:&#x2F;&#x2F;example.com&#x2F;tos&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;URI: https:&#x2F;&#x2F;example.com&#x2F;login&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Chain ID: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce: 32891756&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Issued At: 2021-09-30T16:25:24Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- ipfs:&#x2F;&#x2F;bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- https:&#x2F;&#x2F;example.com&#x2F;my-web2-claim.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The following is an example SIWE Message with an explicit scheme:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;example.com wants you to sign in with your Ethereum account:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&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;I accept the ExampleOrg Terms of Service: https:&#x2F;&#x2F;example.com&#x2F;tos&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;URI: https:&#x2F;&#x2F;example.com&#x2F;login&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Chain ID: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce: 32891756&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Issued At: 2021-09-30T16:25:24Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- ipfs:&#x2F;&#x2F;bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- https:&#x2F;&#x2F;example.com&#x2F;my-web2-claim.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;signing-and-verifying-messages-with-ethereum-accounts&quot;&gt;Signing and Verifying Messages with Ethereum Accounts&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For Externally Owned Accounts (EOAs), the verification method specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; MUST be used.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For Contract Accounts,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The verification method specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; SHOULD be used, and if it is not, the implementer MUST clearly define the verification method to attain security and interoperability for both wallets and relying parties.&lt;&#x2F;li&gt;
&lt;li&gt;When performing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; signature verification, the contract performing the verification MUST be resolved from the specified &lt;code&gt;chain-id&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Implementers SHOULD take into consideration that &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; implementations are not required to be pure functions, and can return different results for the same inputs depending on blockchain state. This can affect the security model and session validation rules. For example, a service with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; signing enabled could rely on webhooks to receive notifications when state affecting the results is changed. When it receives a notification, it invalidates any matching sessions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;resolving-ethereum-name-service-ens-data&quot;&gt;Resolving Ethereum Name Service (ENS) Data&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The relying party or wallet MAY additionally perform resolution of ENS data, as this can improve the user experience by displaying human-friendly information that is related to the &lt;code&gt;address&lt;&#x2F;code&gt;. Resolvable ENS data include:
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;181&#x2F;&quot;&gt;primary ENS name&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The ENS avatar.&lt;&#x2F;li&gt;
&lt;li&gt;Any other resolvable resources specified in the ENS documentation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If resolution of ENS data is performed, implementers SHOULD take precautions to preserve user privacy and consent, as their &lt;code&gt;address&lt;&#x2F;code&gt; could be forwarded to third party services as part of the resolution process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;relying-party-implementer-steps&quot;&gt;Relying Party Implementer Steps&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;specifying-the-request-origin&quot;&gt;Specifying the Request Origin&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;domain&lt;&#x2F;code&gt; and, if present, the &lt;code&gt;scheme&lt;&#x2F;code&gt;, in the SIWE Message MUST correspond to the origin from where the signing request was made. For instance, if the signing request is made within a cross-origin iframe embedded in a parent browser window, the &lt;code&gt;domain&lt;&#x2F;code&gt; (and, if present, the &lt;code&gt;scheme&lt;&#x2F;code&gt;) have to match the origin of the iframe, rather than the origin of the parent. This is crucial to prevent the iframe from falsely asserting the origin of one of its ancestor windows for security reasons. This behavior is enforced by conforming wallets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;verifying-a-signed-message&quot;&gt;Verifying a signed Message&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The SIWE Message MUST be checked for conformance to the ABNF Message Format in the previous sections, checked against expected values after parsing (e.g., &lt;code&gt;expiration-time&lt;&#x2F;code&gt;, &lt;code&gt;nonce&lt;&#x2F;code&gt;, &lt;code&gt;request-uri&lt;&#x2F;code&gt; etc.), and its signature MUST be checked as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#signing-and-verifying-messages-with-ethereum-accounts&quot;&gt;Signing and Verifying Messages with Ethereum Accounts&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;creating-sessions&quot;&gt;Creating Sessions&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Sessions MUST be bound to the &lt;code&gt;address&lt;&#x2F;code&gt; and not to further resolved resources that can change.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;interpreting-and-resolving-resources&quot;&gt;Interpreting and resolving Resources&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Implementers SHOULD ensure that URIs in the listed &lt;code&gt;resources&lt;&#x2F;code&gt; are human-friendly when expressed in plaintext form.&lt;&#x2F;li&gt;
&lt;li&gt;The interpretation of the listed &lt;code&gt;resources&lt;&#x2F;code&gt; in the SIWE Message is out of scope of this specification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;wallet-implementer-steps&quot;&gt;Wallet Implementer Steps&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;verifying-the-message-format&quot;&gt;Verifying the Message Format&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The full SIWE message MUST be checked for conformance to the ABNF defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#abnf-message-format&quot;&gt;ABNF Message Format&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet implementers SHOULD warn users if the substring &lt;code&gt;&quot;wants you to sign in with your Ethereum account&quot;&lt;&#x2F;code&gt; appears anywhere in an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; message signing
request unless the message fully conforms to the format defined &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#abnf-message-format&quot;&gt;ABNF Message Format&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;verifying-the-request-origin&quot;&gt;Verifying the Request Origin&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Wallet implementers MUST prevent phishing attacks by verifying the origin of the request against the &lt;code&gt;scheme&lt;&#x2F;code&gt; and &lt;code&gt;domain&lt;&#x2F;code&gt; fields in the SIWE Message. For example, when processing the SIWE message beginning with &lt;code&gt;&quot;example.com wants you to sign in...&quot;&lt;&#x2F;code&gt;, the wallet checks that the request actually originated from &lt;code&gt;https:&#x2F;&#x2F;example.com&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The origin SHOULD be read from a trusted data source such as the browser window or over WalletConnect (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1328&#x2F;&quot;&gt;ERC-1328&lt;&#x2F;a&gt;) sessions for comparison against the signing message contents.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet implementers MAY warn instead of rejecting the verification if the origin is pointing to localhost.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following is a RECOMMENDED algorithm for Wallets to conform with the requirements on request origin verification defined by this specification.&lt;&#x2F;p&gt;
&lt;p&gt;The algorithm takes the following input variables:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;fields from the SIWE message.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;origin&lt;&#x2F;code&gt; of the signing request - in the case of a browser wallet implementation - the origin of the page which requested the signin via the provider.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;allowedSchemes&lt;&#x2F;code&gt; - a list of schemes allowed by the Wallet.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;defaultScheme&lt;&#x2F;code&gt; - a scheme to assume when none was provided. Wallet implementers in the browser SHOULD use &lt;code&gt;https&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;developer mode indication - a setting deciding if certain risks should be a warning instead of rejection. Can be manually configured or derived from &lt;code&gt;origin&lt;&#x2F;code&gt; being localhost.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The algorithm is described as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;scheme&lt;&#x2F;code&gt; was not provided, then assign &lt;code&gt;defaultScheme&lt;&#x2F;code&gt; as &lt;code&gt;scheme&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;scheme&lt;&#x2F;code&gt; is not contained in &lt;code&gt;allowedSchemes&lt;&#x2F;code&gt;, then the &lt;code&gt;scheme&lt;&#x2F;code&gt; is not expected and the Wallet MUST reject the request. Wallet implementers in the browser SHOULD limit the list of &lt;code&gt;allowedSchemes&lt;&#x2F;code&gt; to just &lt;code&gt;&#x27;https&#x27;&lt;&#x2F;code&gt; unless a developer mode is activated.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;scheme&lt;&#x2F;code&gt; does not match the scheme of &lt;code&gt;origin&lt;&#x2F;code&gt;, the Wallet SHOULD reject the request. Wallet implementers MAY show a warning instead of rejecting the request if a developer mode is activated. In that case the Wallet continues processing the request.&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;host&lt;&#x2F;code&gt; part of the &lt;code&gt;domain&lt;&#x2F;code&gt; and &lt;code&gt;origin&lt;&#x2F;code&gt; do not match, the Wallet MUST reject the request unless the Wallet is in developer mode. In developer mode the Wallet MAY show a warning instead and continues processing the request.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;domain&lt;&#x2F;code&gt; and &lt;code&gt;origin&lt;&#x2F;code&gt; have mismatching subdomains, the Wallet SHOULD reject the request unless the Wallet is in developer mode. In developer mode the Wallet MAY show a warning instead and continues processing the request.&lt;&#x2F;li&gt;
&lt;li&gt;Let &lt;code&gt;port&lt;&#x2F;code&gt; be the port component of &lt;code&gt;domain&lt;&#x2F;code&gt;, and if no port is contained in &lt;code&gt;domain&lt;&#x2F;code&gt;, assign &lt;code&gt;port&lt;&#x2F;code&gt; the default port specified for the &lt;code&gt;scheme&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;port&lt;&#x2F;code&gt; is not empty, then the Wallet SHOULD show a warning if the &lt;code&gt;port&lt;&#x2F;code&gt; does not match the port of &lt;code&gt;origin&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;port&lt;&#x2F;code&gt; is empty, then the Wallet MAY show a warning if &lt;code&gt;origin&lt;&#x2F;code&gt; contains a specific port. (Note &#x27;https&#x27; has a default port of 443 so this only applies if &lt;code&gt;allowedSchemes&lt;&#x2F;code&gt; contain unusual schemes)&lt;&#x2F;li&gt;
&lt;li&gt;Return request origin verification completed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;creating-sign-in-with-ethereum-interfaces&quot;&gt;Creating Sign-In with Ethereum Interfaces&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Wallet implementers MUST display to the user the following fields from the SIWE Message request by default and prior to signing, if they are present: &lt;code&gt;scheme&lt;&#x2F;code&gt;, &lt;code&gt;domain&lt;&#x2F;code&gt;, &lt;code&gt;address&lt;&#x2F;code&gt;, &lt;code&gt;statement&lt;&#x2F;code&gt;, and &lt;code&gt;resources&lt;&#x2F;code&gt;. Other present fields MUST also be made available to the user prior to signing either by default or through an extended interface.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet implementers displaying a plaintext SIWE Message to the user SHOULD require the user to scroll to the bottom of the text area prior to signing.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet implementers MAY construct a custom SIWE user interface by parsing the ABNF terms into data elements for use in the interface. The display rules above still apply to custom interfaces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;supporting-internationalization-i18n&quot;&gt;Supporting internationalization (i18n)&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;After successfully parsing the message into ABNF terms, translation MAY happen at the UX level per human language.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;Write a specification for how Sign-In with Ethereum should work. The specification should be simple and generally follow existing practices. Avoid feature bloat, particularly the inclusion of lesser-used projects who see getting into the specification as a means of gaining adoption. The core specification should be decentralized, open, non-proprietary, and have long-term viability. It should have no dependence on a centralized server except for the servers already being run by the application that the user is signing in to. The basic specification should include: Ethereum accounts used for authentication, ENS names for usernames (via reverse resolution), and data from the ENS name’s text records for additional profile information (e.g. avatar, social media handles, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Additional functional requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The user must be presented a human-understandable interface prior to signing, mostly free of machine-targeted artifacts such as JSON blobs, hex codes (aside from the Ethereum address), and baseXX-encoded strings.&lt;&#x2F;li&gt;
&lt;li&gt;The application server must be able to implement fully usable support for its end without forcing a change in the wallets.&lt;&#x2F;li&gt;
&lt;li&gt;There must be a simple and straightforward upgrade path for both applications and wallets already using Ethereum account-based signing for authentication.&lt;&#x2F;li&gt;
&lt;li&gt;There must be facilities and guidelines for adequate mitigation of Man-in-the-Middle (MITM) attacks, replay attacks, and malicious signing requests.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;design-goals&quot;&gt;Design Goals&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Human-Friendly&lt;&#x2F;li&gt;
&lt;li&gt;Simple to Implement&lt;&#x2F;li&gt;
&lt;li&gt;Secure&lt;&#x2F;li&gt;
&lt;li&gt;Machine Readable&lt;&#x2F;li&gt;
&lt;li&gt;Extensible&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;technical-decisions&quot;&gt;Technical Decisions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Why &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; (Signed Data Standard) over &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; (Ethereum typed structured data hashing and signing)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; is already broadly supported across wallets UX, while &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; support for friendly user display is pending. &lt;strong&gt;(1, 2, 3, 4)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; is simple to implement using a pre-set prefix prior to signing, while &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; is more complex to implement requiring the further implementations of a bespoke Solidity-inspired type system, RLP-based encoding format, and custom keccak-based hashing scheme. &lt;strong&gt;(2)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt; produces more human-readable messages, while &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; creates signing outputs for machine consumption, with most wallets not displaying the payload to be signed in a manner friendly to humans. &lt;strong&gt;(1)&lt;&#x2F;strong&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;.&#x2F;assets&#x2F;signing.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt; has the advantage of on-chain representation and on-chain verifiability, such as for their use in metatransactions, but this feature is not relevant for the specification&#x27;s scope. &lt;strong&gt;(2)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Why not use JWTs? Wallets don&#x27;t support JWTs. The keccak hash function is not assigned by IANA for use as a JOSE algorithm. &lt;strong&gt;(2, 3)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Why not use YAML or YAML with exceptions? YAML is loose compared to ABNF, which can readily express character set limiting, required ordering, and strict whitespacing. &lt;strong&gt;(2, 3)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;out-of-scope&quot;&gt;Out of Scope&lt;&#x2F;h3&gt;
&lt;p&gt;The following concerns are out of scope for this version of the specification to define:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Additional authentication not based on Ethereum addresses.&lt;&#x2F;li&gt;
&lt;li&gt;Authorization to server resources.&lt;&#x2F;li&gt;
&lt;li&gt;Interpretation of the URIs in the &lt;code&gt;resources&lt;&#x2F;code&gt; field as claims or other resources.&lt;&#x2F;li&gt;
&lt;li&gt;The specific mechanisms to ensure domain-binding.&lt;&#x2F;li&gt;
&lt;li&gt;The specific mechanisms to generate nonces and evaluation of their appropriateness.&lt;&#x2F;li&gt;
&lt;li&gt;Protocols for use without TLS connections.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;considerations-for-forwards-compatibility&quot;&gt;Considerations for Forwards Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;The following items are considered for future support either through an iteration of this specification or new work items using this specification as a dependency.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Possible support for Decentralized Identifiers and Verifiable Credentials.&lt;&#x2F;li&gt;
&lt;li&gt;Possible cross-chain support.&lt;&#x2F;li&gt;
&lt;li&gt;Possible SIOPv2 support.&lt;&#x2F;li&gt;
&lt;li&gt;Possible future support for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Version interpretation rules, e.g., sign with minor revision greater than understood, but not greater major version.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Most wallet implementations already support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt;, so this is used as a base pattern with additional features.&lt;&#x2F;li&gt;
&lt;li&gt;Requirements were gathered from existing implementations of similar sign-in workflows, including statements to allow the user to accept a Terms of Service, nonces for replay protection, and inclusion of the Ethereum address itself in the message.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation is available &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;.&#x2F;assets&#x2F;example.js&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;identifier-reuse&quot;&gt;Identifier Reuse&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Towards perfect privacy, it would be ideal to use a new uncorrelated identifier (e.g., Ethereum address) per digital interaction, selectively disclosing the information required and no more.&lt;&#x2F;li&gt;
&lt;li&gt;This concern is less relevant to certain user demographics who are likely to be early adopters of this specification, such as those who manage an Ethereum address and&#x2F;or ENS names intentionally associated with their public presence. These users often prefer identifier reuse to maintain a single correlated identity across many services.&lt;&#x2F;li&gt;
&lt;li&gt;This consideration will become increasingly important with mainstream adoption. There are several ways to move towards this model, such as using HD wallets, signed delegations, and zero-knowledge proofs. However, these approaches are out of scope for this specification and better suited for follow-on specifications.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;key-management&quot;&gt;Key Management&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Sign-In with Ethereum gives users control through their keys. This is additional responsibility that mainstream users may not be accustomed to accepting, and key management is a hard problem especially for individuals. For example, there is no &quot;forgot password&quot; button as centralized identity providers commonly implement.&lt;&#x2F;li&gt;
&lt;li&gt;Early adopters of this specification are likely to be already adept at key management, so this consideration becomes more relevant with mainstream adoption.&lt;&#x2F;li&gt;
&lt;li&gt;Certain wallets can use smart contracts and multisigs to provide an enhanced user experience with respect to key usage and key recovery, and these can be supported via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; signing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;wallet-and-relying-party-combined-security&quot;&gt;Wallet and Relying Party combined Security&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Both the wallet and relying party have to implement this specification for improved security to the end user. Specifically, the wallet has to confirm that the SIWE Message is for the correct request origin or provide the user means to do so manually (such as instructions to visually confirming the correct domain in a TLS-protected website prior to connecting via QR code or deeplink), otherwise the user is subject to phishing attacks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;minimizing-wallet-and-server-interaction&quot;&gt;Minimizing Wallet and Server Interaction&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;In some implementations of wallet sign-in workflows, the server first sends parameters of the SIWE Message to the wallet. Others generate the SIWE message for signing entirely in the client side (e.g., dapps). The latter approach without initial server interaction SHOULD be preferred when there is a user privacy advantage by minimizing wallet-server interaction. Often, the backend server first produces a &lt;code&gt;nonce&lt;&#x2F;code&gt; to prevent replay attacks, which it verifies after signing. Privacy-preserving alternatives are suggested in the next section on preventing replay attacks.&lt;&#x2F;li&gt;
&lt;li&gt;Before the wallet presents the SIWE message signing request to the user, it MAY consult the server for the proper contents of the message to be signed, such as an acceptable &lt;code&gt;nonce&lt;&#x2F;code&gt; or requested set of &lt;code&gt;resources&lt;&#x2F;code&gt;. When communicating to the server, the wallet SHOULD take precautions to protect user privacy by mitigating user information revealed as much as possible.&lt;&#x2F;li&gt;
&lt;li&gt;Prior to signing, the wallet MAY consult the user for preferences, such as the selection of one &lt;code&gt;address&lt;&#x2F;code&gt; out of many, or a preferred ENS name out of many.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;preventing-replay-attacks&quot;&gt;Preventing Replay Attacks&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;nonce&lt;&#x2F;code&gt; SHOULD be selected per session initiation with enough entropy to prevent replay attacks, a man-in-the-middle attack in which an attacker is able to capture the user&#x27;s signature and resend it to establish a new session for themselves.&lt;&#x2F;li&gt;
&lt;li&gt;Implementers MAY consider using privacy-preserving yet widely-available &lt;code&gt;nonce&lt;&#x2F;code&gt; values, such as one derived from a recent Ethereum block hash or a recent Unix timestamp.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;preventing-phishing-attacks&quot;&gt;Preventing Phishing Attacks&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;To prevent phishing attacks Wallets have to implement request origin verification as described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4361&#x2F;#verifying-the-request-origin&quot;&gt;Verifying the Request Origin&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;channel-security&quot;&gt;Channel Security&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;For web-based applications, all communications SHOULD use HTTPS to prevent man-in-the-middle attacks on the message signing.&lt;&#x2F;li&gt;
&lt;li&gt;When using protocols other than HTTPS, all communications SHOULD be protected with proper techniques to maintain confidentiality, data integrity, and sender&#x2F;receiver authenticity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;session-invalidation&quot;&gt;Session Invalidation&lt;&#x2F;h3&gt;
&lt;p&gt;There are several cases where an implementer SHOULD check for state changes as they relate to sessions.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1271&#x2F;&quot;&gt;ERC-1271&lt;&#x2F;a&gt; implementation or dependent data changes the signature computation, the server SHOULD invalidate sessions appropriately.&lt;&#x2F;li&gt;
&lt;li&gt;If any resources specified in &lt;code&gt;resources&lt;&#x2F;code&gt; change, the server SHOULD invalidate sessions appropriately. However, the interpretation of &lt;code&gt;resources&lt;&#x2F;code&gt; is out of scope of this specification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;maximum-lengths-for-abnf-terms&quot;&gt;Maximum Lengths for ABNF Terms&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;While this specification does not contain normative requirements around maximum string lengths, implementers SHOULD choose maximum lengths for terms that strike a balance across the prevention of denial of service attacks, support for arbitrary use cases, and user readability.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Difficulty Bomb Delay to June 2022</title>
        <published>2021-10-05T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	<author>
		<name>James Hancock</name><uri>https://github.com/MadeOfTin</uri>
	</author>
	
	<author>
		<name>Thomas Jay Rush</name><uri>https://github.com/tjayrush</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4345/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4345-difficulty-bomb-delay-to-may-2022/7209" />
        

        <id>https://wg-eips.ritovision.com/4345/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:4345"
            label="EIP-4345" />
        

        
        

        
        <summary type="html">Delays the difficulty bomb to be noticeable in June 2022.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4345/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 10,700,000 blocks later than the actual block number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Targeting for The Merge to occur before June 2022. If it is not ready by then, the bomb can be delayed further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fake_block_number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10_700_000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The following script predicts a ~0.1 second delay to block time by June 2022 and a ~0.5 second delay by July 2022. This gives reason to address because the effect will be seen, but not so much urgency we don&#x27;t have space to work around if needed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; predict_diff_bomb_effect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;current_blknum&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; current_difficulty&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block_adjustment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; months&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Predicts the effect on block time (as a ratio) in a specified amount of months in the future.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Vars used for predictions:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    current_blknum = 13423376 # Oct 15, 2021&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    current_difficulty = 9545154427582720&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    block adjustment = 10700000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    months = 7.5 # June 2022&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    months = 8.5 # July 2022&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blocks_per_month&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;86400&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    future_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; current_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; blocks_per_month&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; months&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    diff_adjustment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; **&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;future_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; block_adjustment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; diff_adjustment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; current_difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2048&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; diff_adjust_coeff&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; predict_diff_bomb_effect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;13423376&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9545154427582720&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10700000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7.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&gt;diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; predict_diff_bomb_effect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;13423376&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9545154427582720&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10700000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8.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;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No known backward compatibility issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Misjudging the effects of the difficulty can mean longer blocktimes than anticipated until a hardfork is released. Wild shifts in difficulty can affect this number severely. Also, gradual changes in blocktimes due to longer-term adjustments in difficulty can affect the timing of difficulty bomb epochs. This affects the usability of the network but unlikely to have security ramifications.&lt;&#x2F;p&gt;
&lt;p&gt;In this specific instance, it is possible that the network hashrate drops considerably before The Merge, which could accelerate the timeline by which the bomb is felt in block times. The offset value chosen aimed to take this into account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Upgrade consensus to Proof-of-Stake</title>
        <published>2021-07-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mikhail Kalinin</name><uri>https://github.com/mkalinin</uri>
	</author>
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3675/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3675-upgrade-consensus-to-proof-of-stake/6706" />
        

        <id>https://wg-eips.ritovision.com/3675/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:3675"
            label="EIP-3675" />
        

        
        

        
        <summary type="html">Specification of the consensus mechanism upgrade on Ethereum Mainnet that introduces Proof-of-Stake</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3675/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP deprecates Proof-of-Work (PoW) and supersedes it with the new Proof-of-Stake consensus mechanism (PoS) driven by the beacon chain. Information on the bootstrapping of the new consensus mechanism is documented in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;&quot;&gt;EIP-2982&lt;&#x2F;a&gt;. Full specification of the beacon chain can be found in the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;p&gt;This document specifies the set of changes to the block structure, block processing, fork choice rule and network interface introduced by the consensus upgrade.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The beacon chain network has been up and running since December 2020. Neither safety nor liveness failures were detected during this period of time. This long period of running without failure demonstrates the sustainability of the beacon chain system and its readiness to become a security provider for the Ethereum Mainnet.&lt;&#x2F;p&gt;
&lt;p&gt;To understand the motivation of introducing the Proof-of-Stake consensus see the Motivation section of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;#motivation&quot;&gt;EIP-2982&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PoW block&lt;&#x2F;strong&gt;: Block that is built and verified by the existing proof-of-work mechanism. In other words, a block of the Ethereum network before the consensus upgrade.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PoS block&lt;&#x2F;strong&gt;: Block that is built and verified by the new proof-of-stake mechanism.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Terminal PoW block&lt;&#x2F;strong&gt;: A PoW block that satisfies the following conditions --
&lt;code&gt;pow_block.total_difficulty &amp;gt;= TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt; &lt;em&gt;and&lt;&#x2F;em&gt; &lt;code&gt;pow_block.parent_block.total_difficulty &amp;lt; TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt;.
There can be more than one terminal PoW block in the network, e.g. multiple children of the same pre-terminal block.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The amount of total difficulty reached by the network that triggers the consensus upgrade. Ethereum Mainnet configuration &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have this parameter set to the value &lt;code&gt;58750000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The earliest PoS block of the canonical chain, i.e. the PoS block with the lowest block height.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; An event occurring when the state of the proof-of-stake fork choice is updated.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; A block number set to the &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; parameter for the upcoming consensus upgrade.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; Designates the hash of the terminal PoW block if set, i.e. if not stubbed with &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TERMINAL_BLOCK_NUMBER&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; Designates the number of the terminal PoW block if &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; is set.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;pos-events&quot;&gt;PoS events&lt;&#x2F;h4&gt;
&lt;p&gt;Events having the &lt;code&gt;POS_&lt;&#x2F;code&gt; prefix in the name (PoS events) are emitted by the new proof-of-stake consensus mechanism. They signify the corresponding assertion that has been made regarding a block specified by the event. The underlying logic of PoS events can be found in the beacon chain specification. On the occurrence of each PoS event the corresponding action that is specified by this EIP &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be taken.&lt;&#x2F;p&gt;
&lt;p&gt;The details provided below must be taken into account when reading those parts of the specification that refer to the PoS events:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reference to a block that is contained by PoS events is provided in a form of a block hash unless another is explicitly specified.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event contains references to the head of the canonical chain and to the most recent finalized block. Before the first finalized block occurs in the system the finalized block hash provided by this event is stubbed with &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The first finalized block that is designated by &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event and has the hash that differs from the stub.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;client-software-configuration&quot;&gt;Client software configuration&lt;&#x2F;h3&gt;
&lt;p&gt;The following set of parameters is a part of client software configuration and &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be included into its binary distribution:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_BLOCK_NUMBER&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: If &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; is stubbed with &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt; then &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; and &lt;code&gt;TERMINAL_BLOCK_NUMBER&lt;&#x2F;code&gt; parameters &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; take an effect.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pow-block-processing&quot;&gt;PoW block processing&lt;&#x2F;h3&gt;
&lt;p&gt;PoW blocks that are descendants of any terminal PoW block &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be imported. This implies that a terminal PoW block will be the last PoW block in the canonical chain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;MAX_EXTRA_DATA_BYTES&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;block-structure&quot;&gt;Block structure&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, a number of previously dynamic block fields are deprecated by enforcing these values to instead be constants. Each block field listed in the table below &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be replaced with the corresponding constant value.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Field&lt;&#x2F;th&gt;&lt;th&gt;Constant value&lt;&#x2F;th&gt;&lt;th&gt;Comment&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;ommersHash&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;= Keccak256(RLP([]))&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;mixHash&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;nonce&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;ommers&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;[]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;RLP([]) = 0xc0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, the validation of the block&#x27;s &lt;strong&gt;&lt;code&gt;extraData&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; field changes: The length of the block&#x27;s &lt;strong&gt;&lt;code&gt;extraData&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be less than or equal to &lt;strong&gt;&lt;code&gt;MAX_EXTRA_DATA_BYTES&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; bytes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: Logic and validity conditions of block fields that are &lt;em&gt;not&lt;&#x2F;em&gt; specified here &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remain unchanged. Additionally, the overall block format &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remain unchanged.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: Subsequent EIPs may override the constant values specified above to provide additional functionality. For an example, see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4399&#x2F;&quot;&gt;EIP-4399&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-validity&quot;&gt;Block validity&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, the block validity conditions &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be altered by the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Remove verification of the block&#x27;s &lt;strong&gt;&lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; value with respect to the difficulty formula.&lt;&#x2F;li&gt;
&lt;li&gt;Remove verification of the block&#x27;s &lt;strong&gt;&lt;code&gt;nonce&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; and &lt;strong&gt;&lt;code&gt;mixHash&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; values with respect to the Ethash function.&lt;&#x2F;li&gt;
&lt;li&gt;Remove all validation rules that are evaluated over the list of ommers and each member of this list.&lt;&#x2F;li&gt;
&lt;li&gt;Add verification of the fields noted in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#block-structure&quot;&gt;block structure&lt;&#x2F;a&gt; section.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: If one of the new rules fails then the block &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be invalidated.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: Validity rules that are not specified in the list above &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remain unchanged.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;transition-block-validity&quot;&gt;Transition block validity&lt;&#x2F;h4&gt;
&lt;p&gt;In addition to satisfying the above conditions, &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be a child of a terminal PoW block. That is, a parent of &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; satisfy terminal PoW block conditions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-and-ommer-rewards&quot;&gt;Block and ommer rewards&lt;&#x2F;h3&gt;
&lt;p&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, block and ommer rewards are deprecated. Specifically, the following actions &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be taken:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Remove increasing the balance of the block&#x27;s &lt;strong&gt;&lt;code&gt;beneficiary&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; account by the block reward.&lt;&#x2F;li&gt;
&lt;li&gt;Remove increasing the balance of the block&#x27;s &lt;strong&gt;&lt;code&gt;beneficiary&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; account by the ommer inclusion reward per each ommer.&lt;&#x2F;li&gt;
&lt;li&gt;Remove increasing the balance of the ommer&#x27;s &lt;strong&gt;&lt;code&gt;beneficiary&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; account by the ommer block reward per each ommer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: Transaction fee mechanics affecting the block&#x27;s &lt;code&gt;beneficiary&lt;&#x2F;code&gt; account &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remain unchanged.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fork-choice-rule&quot;&gt;Fork choice rule&lt;&#x2F;h3&gt;
&lt;p&gt;If set, &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; parameter affects the PoW heaviest chain rule in the following way:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Canonical blockchain &lt;strong&gt;MUST&lt;&#x2F;strong&gt; contain a block with the hash defined by &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; parameter at the height defined by &lt;code&gt;TERMINAL_BLOCK_NUMBER&lt;&#x2F;code&gt; parameter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: This rule is akin to block hash whitelisting functionality already present in client software implementations.&lt;&#x2F;p&gt;
&lt;p&gt;As of the first &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event, the fork choice rule &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be altered in the following way:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Remove the existing PoW heaviest chain rule.&lt;&#x2F;li&gt;
&lt;li&gt;Adhere to the new PoS LMD-GHOST rule.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The new PoS LMD-GHOST fork choice rule is specified as follows. On each occurrence of a &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event including the first one, the following actions &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be taken:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Consider the chain starting at genesis and ending with the head block nominated by the event as the canonical blockchain.&lt;&#x2F;li&gt;
&lt;li&gt;Set the head of the canonical blockchain to the corresponding block nominated by the event.&lt;&#x2F;li&gt;
&lt;li&gt;Beginning with the &lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt;, set the most recent finalized block to the corresponding block nominated by the event.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Changes to the block tree store that are related to the above actions &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be applied atomically.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: This rule &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be strictly enforced. &quot;Optimistic&quot; updates to the head &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be made. That is -- if a new block is processed on top of the current head block, this new block becomes the new head if and only if an accompanying &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event occurs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;network&quot;&gt;Network&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;fork-identifier&quot;&gt;Fork identifier&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt; fork identifier, nodes implementing this EIP &lt;strong&gt;MUST&lt;&#x2F;strong&gt; set the &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; parameter to the &lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;devp2p&quot;&gt;devp2p&lt;&#x2F;h4&gt;
&lt;p&gt;The networking stack &lt;strong&gt;SHOULD NOT&lt;&#x2F;strong&gt; send the following messages if they advertise the descendant of any terminal PoW block:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NewBlockHashes (0x01)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Beginning with receiving the &lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt;, the networking stack &lt;strong&gt;MUST&lt;&#x2F;strong&gt; discard the following ingress messages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NewBlockHashes (0x01)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Beginning with receiving the finalized block next to the &lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt;, the networking stack &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remove the handlers corresponding to the following messages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NewBlockHashes (0x01)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Peers that keep sending these messages after the handlers have been removed &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be disconnected.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;&#x2F;em&gt; The logic of message handlers that are not affected by this section &lt;strong&gt;MUST&lt;&#x2F;strong&gt; remain unchanged.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The changes specified in this EIP target a minimal requisite set of consensus and client software modifications to safely replace the existing proof-of-work consensus algorithm with the new proof-of-stake consensus represented by the already in-production beacon chain.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP was designed to minimize the complexity of hot-swapping the live consensus of the Ethereum network. Both the safety of the operation and time to production were taken into consideration. Additionally, a minimal changeset helps ensure that &lt;em&gt;most&lt;&#x2F;em&gt; smart contracts and services will continue to function as intended during and after the transition with little to no required intervention.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;total-difficulty-triggering-the-upgrade&quot;&gt;Total difficulty triggering the upgrade&lt;&#x2F;h3&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#terminal-total-difficulty-vs-block-number&quot;&gt;Security considerations&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameterizing-terminal-block-hash&quot;&gt;Parameterizing terminal block hash&lt;&#x2F;h3&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#terminal-pow-block-overriding&quot;&gt;Security considerations&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;halting-the-import-of-pow-blocks&quot;&gt;Halting the import of PoW blocks&lt;&#x2F;h3&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#halt-the-importing-of-pow-blocks&quot;&gt;Security considerations&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replacing-block-fields-with-constants&quot;&gt;Replacing block fields with constants&lt;&#x2F;h3&gt;
&lt;p&gt;Deprecated block fields are replaced with constant values to ensure the block format remains backwards compatible. Preserving the block format aids existing smart contracts and services in providing uninterrupted service during and after this transition.&lt;&#x2F;p&gt;
&lt;p&gt;Particularly, this is important for those smart contracts that verify Merkle proofs of transaction&#x2F;receipt inclusion and state by validating the hash of externally provided block header against the corresponding value returned by the &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; operation.&lt;&#x2F;p&gt;
&lt;p&gt;This change introduces an additional validity rule that enforces the replacement of deprecated block fields.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replacing-difficulty-with-0&quot;&gt;Replacing &lt;code&gt;difficulty&lt;&#x2F;code&gt; with &lt;code&gt;0&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;After deprecating the proof-of-work the notion of difficulty no longer exists and replacing the block header &lt;strong&gt;&lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; field with &lt;code&gt;0&lt;&#x2F;code&gt; constant is semantically sound.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;changing-block-validity-rules&quot;&gt;Changing block validity rules&lt;&#x2F;h3&gt;
&lt;p&gt;The rule set enforcing the PoW seal validity is replaced with the corresponding PoS rules along with the consensus upgrade as the rationale behind this change.&lt;&#x2F;p&gt;
&lt;p&gt;An additional rule validating a set of deprecated block fields is required by the block format changes introduced by this specification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removing-block-rewards&quot;&gt;Removing block rewards&lt;&#x2F;h3&gt;
&lt;p&gt;Existing rewards for producing and sealing blocks are deprecated along with the PoW mechanism. The new PoS consensus becomes both responsible for sealing blocks and for issuing block rewards once this specification enters into effect.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;supplanting-fork-choice-rule&quot;&gt;Supplanting fork choice rule&lt;&#x2F;h3&gt;
&lt;p&gt;The fork choice rule of the PoW mechanism becomes completely irrelevant after the upgrade and is replaced with the corresponding rule of the new PoS consensus mechanism.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;remove-of-pos-consensus-validated&quot;&gt;Remove of &lt;code&gt;POS_CONSENSUS_VALIDATED&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;In prior draft versions of this EIP, an additional POS event -- &lt;code&gt;POS_CONSENSUS_VALIDATED&lt;&#x2F;code&gt; -- was required as a validation condition for blocks. This event gave the signal to either fully incorporate or prune the block from the block tree.&lt;&#x2F;p&gt;
&lt;p&gt;This event was removed for two reasons:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;This event was an unnecessary optimization to allow for pruning of &quot;bad&quot; blocks from the block tree. This optimization was unnecessary because the PoS consensus would never send &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; for any such bad blocks or their descendants, and eventually any such blocks would be able to be pruned after a PoS finality event of an alternative branch in the block tree.&lt;&#x2F;li&gt;
&lt;li&gt;This event was dangerous in some scenarios because a block could be referenced by two &lt;em&gt;different&lt;&#x2F;em&gt; and conflicting PoS branches. Thus for the same block in some scenarios, both a &lt;code&gt;POS_CONSENSUS_VALIDATED == TRUE&lt;&#x2F;code&gt; and &lt;code&gt;POS_CONSENSUS_VALIDATED == FALSE&lt;&#x2F;code&gt; event could sent, entirely negating the ability to safely perform the optimization in (1).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;eip-2124-fork-identifier&quot;&gt;EIP-2124 fork identifier&lt;&#x2F;h3&gt;
&lt;p&gt;The value of &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; in EIP-2124 refers to the block number of the next fork a given node knows about and &lt;code&gt;0&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;The number of &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; cannot be known ahead of time given the dynamic nature of the transition trigger condition. As the block will not be known a priori, nodes can&#x27;t use its number for &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; and in light of this fact an explicitly set &lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt; is used instead.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;removing-block-gossip&quot;&gt;Removing block gossip&lt;&#x2F;h3&gt;
&lt;p&gt;After the upgrade of the consensus mechanism only the beacon chain network will have enough information to validate a block. Thus, block gossip provided by the &lt;code&gt;eth&lt;&#x2F;code&gt; network protocol will become unsafe and is deprecated in favour of the block gossip existing in the beacon chain network.&lt;&#x2F;p&gt;
&lt;p&gt;It is recommended for the client software to not propagate descendants of any terminal PoW block to reduce the load on processing the P2P component and stop operating in the environment with unknown security properties.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;restricting-the-length-of-extradata&quot;&gt;Restricting the length of &lt;code&gt;extraData&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;extraData&lt;&#x2F;code&gt; field is defined as a maximum of &lt;code&gt;32&lt;&#x2F;code&gt; bytes in the yellow paper. Thus mainnet and most PoW testnets cap the value at &lt;code&gt;32&lt;&#x2F;code&gt; bytes.  &lt;code&gt;extraData&lt;&#x2F;code&gt; fields of greater length are used by clique testnets and other networks to carry special signature&#x2F;consensus schemes. This EIP restricts the length of &lt;code&gt;extraData&lt;&#x2F;code&gt; to &lt;code&gt;32&lt;&#x2F;code&gt; bytes because any network that is transitioning from another consensus mechanism to a beacon chain PoS consensus mechanism no longer needs extended or unbounded &lt;code&gt;extraData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backward incompatibilities in block validity, block rewards and fork choice rule.&lt;&#x2F;p&gt;
&lt;p&gt;The design of the consensus upgrade specified by this document does not introduce backward incompatibilities for existing applications and services built on top of Ethereum except for those that are described in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3675&#x2F;#evm&quot;&gt;EVM&lt;&#x2F;a&gt; section below or heavily depends on the PoW consensus in any other way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;evm&quot;&gt;EVM&lt;&#x2F;h3&gt;
&lt;p&gt;Although this EIP does not introduce any explicit changes to the EVM there are a couple of places where it may affect the logic of existing smart contracts.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;difficulty&quot;&gt;DIFFICULTY&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; operation will always return &lt;code&gt;0&lt;&#x2F;code&gt; after this EIP takes effect and deprecates the &lt;strong&gt;&lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; field by replacing it with &lt;code&gt;0&lt;&#x2F;code&gt; constant.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;&#x2F;em&gt; Altering the &lt;code&gt;DIFFICULTY&lt;&#x2F;code&gt; semantics to return randomness accumulated by the beacon chain is under consideration but will be introduced in a separate EIP.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;blockhash&quot;&gt;BLOCKHASH&lt;&#x2F;h4&gt;
&lt;p&gt;Pseudo-random numbers obtained as the output of &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; operation become more insecure after this EIP takes effect and the PoW mechanism (which decreases the malleability of block hashes) gets supplanted by PoS.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Block validity
&lt;ul&gt;
&lt;li&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, block is invalidated if any of the following is true:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ommersHash != Keccak256(RLP([]))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;difficulty != 0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;nonce != 0x0000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;len(extraData) &amp;gt; MAX_EXTRA_DATA_BYTES&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, block rewards aren&#x27;t added to &lt;code&gt;beneficiary&lt;&#x2F;code&gt; account&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Client software adheres to PoS LMD-GHOST rule
&lt;ul&gt;
&lt;li&gt;Head and finalized blocks are set according to the recent &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event&lt;&#x2F;li&gt;
&lt;li&gt;No fork choice state is updated unless &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt; event is received&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Transition process
&lt;ul&gt;
&lt;li&gt;Client software doesn&#x27;t process any PoW block beyond a terminal PoW block&lt;&#x2F;li&gt;
&lt;li&gt;Beginning with &lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt;, client software applies new block validity rules&lt;&#x2F;li&gt;
&lt;li&gt;Beginning with the first &lt;code&gt;POS_FORKCHOICE_UPDATED&lt;&#x2F;code&gt;, client software switches its fork choice rule to PoS LMD-GHOST&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TRANSITION_BLOCK&lt;&#x2F;code&gt; must be a child of a terminal PoW block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NewBlockHashes (0x01)&lt;&#x2F;code&gt; and &lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt; network messages are discarded after receiving the &lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;beacon-chain&quot;&gt;Beacon chain&lt;&#x2F;h3&gt;
&lt;p&gt;See Security Considerations section of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;#security-considerations&quot;&gt;EIP-2982&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transition-process&quot;&gt;Transition process&lt;&#x2F;h3&gt;
&lt;p&gt;The transition process used to take this specification into effect is a more sophisticated version of a hardfork -- the regular procedure of applying backwards incompatible changes in the Ethereum network. This process has multiple successive steps instead of the normal block-height point condition of simpler hardforks.&lt;&#x2F;p&gt;
&lt;p&gt;The complexity of this upgrade process stems from this fork targeting the underlying consensus mechanism rather than the execution layer within the consensus mechanism. Although the design seeks simplicity where possible, safety and liveness considerations during this transition have been prioritized.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;terminal-total-difficulty-vs-block-number&quot;&gt;Terminal total difficulty vs block number&lt;&#x2F;h4&gt;
&lt;p&gt;Using a pre-defined block number for the hardfork is unsafe in this context due to the PoS fork choice taking priority during the transition.&lt;&#x2F;p&gt;
&lt;p&gt;An attacker may use a minority of hash power to build a malicious chain fork that would satisfy the block height requirement. Then the first PoS block may be maliciously proposed on top of the PoW block from this adversarial fork, becoming the head and subverting the security of the transition.&lt;&#x2F;p&gt;
&lt;p&gt;To protect the network from this attack scenario, difficulty accumulated by the chain (total difficulty) is used to trigger the upgrade.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;ability-to-jump-between-terminal-pow-blocks&quot;&gt;Ability to jump between terminal PoW blocks&lt;&#x2F;h4&gt;
&lt;p&gt;There could be the case when a terminal PoW block is not observed by the majority of network participants due to (temporal) network partitioning. In such a case, this minority would switch their fork choice to the new rule provided by the PoS rooted on the minority terminal PoW block that they observed.&lt;&#x2F;p&gt;
&lt;p&gt;The transition process allows the network to re-org between forks with different terminal PoW blocks as long as (a) these blocks satisfy the terminal PoW block conditions and (b) the &lt;code&gt;FIRST_FINALIZED_BLOCK&lt;&#x2F;code&gt; has not yet been received. This provides resilience against adverse network conditions during the transition process and prevents irreparable forks&#x2F;partitions.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;halt-the-importing-of-pow-blocks&quot;&gt;Halt the importing of PoW blocks&lt;&#x2F;h4&gt;
&lt;p&gt;Suppose the part of the client software that is connected to the beacon chain network goes offline before the Ethereum network reaches the &lt;code&gt;TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt; and stays offline while the network meets this threshold. Such an event makes the client software unable to switch to PoS and allows it to keep following the PoW chain if this chain is being built beyond the terminal PoW block. Depending on how long the beacon chain part was offline, it could result in different adverse effects such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The client has no post-state for the terminal PoW block (the state has been pruned) which prevents it from doing the re-org to the PoS chain and leaving syncing from scratch as the only option to recover.&lt;&#x2F;li&gt;
&lt;li&gt;An application, a user or a service uses the data from the wrong fork (PoW chain that is kept being built) which can cause security issues on their side.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Not importing PoW blocks that are beyond the terminal PoW block prevents these adverse effects on safety&#x2F;re-orgs in the event of software or configuration failures &lt;em&gt;in favor&lt;&#x2F;em&gt; of a liveness failure.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;terminal-pow-block-overriding&quot;&gt;Terminal PoW block overriding&lt;&#x2F;h4&gt;
&lt;p&gt;There is a mechanism allowing for accelerating the consensus upgrade in emergency cases.
This EIP considers the following emergency case scenarios for the acceleration to come into effect:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A drop of the network hashing rate which delays the upgrade significantly.&lt;&#x2F;li&gt;
&lt;li&gt;Attacks on the PoW network before the upgrade.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first case can be safely accelerated by updating the following parameters:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt; -- reset to a value that is closer in time than the original one.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt; -- adjust accordingly.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The second, more dire attack scenario requires a more invasive override:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt; -- set to the hash of a certain block to become the terminal PoW block.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_BLOCK_NUMBER&lt;&#x2F;code&gt; -- set to the number of a block designated by &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TERMINAL_TOTAL_DIFFICULTY&lt;&#x2F;code&gt; -- set to the total difficulty value of a block designated by &lt;code&gt;TERMINAL_BLOCK_HASH&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FORK_NEXT_VALUE&lt;&#x2F;code&gt; -- adjust accordingly.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: Acceleration in the second case is considered for the most extreme of scenarios because it will result in a non-trivial liveness failure on Ethereum Mainnet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ancient-blocks-are-no-longer-a-requisite-for-a-network-security&quot;&gt;Ancient blocks are no longer a requisite for a network security&lt;&#x2F;h3&gt;
&lt;p&gt;Keeping historical blocks starting from genesis is essential in the PoW network. A header of every block that belongs to a particular chain is required to justify the validity of this chain with respect to the PoW seal.&lt;&#x2F;p&gt;
&lt;p&gt;Validating the entire history of the chain is not required by the new PoS mechanism. Instead, the sync process in the PoS network relies on weak subjectivity checkpoints, which are historical snapshots shared by peers on the network. This means historical blocks beyond weak subjectivity checkpoint are no longer a requisite for determining the canonical blockchain.&lt;&#x2F;p&gt;
&lt;p&gt;Specification of weak subjectivity checkpoints can be found in the &lt;code&gt;ethereum&#x2F;consensus-specs&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Limit and meter initcode</title>
        <published>2021-07-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Martin Holst Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	<author>
		<name>Paweł Bylica</name><uri>https://github.com/chfast</uri>
	</author>
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Andrei Maiboroda</name><uri>https://github.com/gumb0</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3860/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3860-limit-and-meter-initcode/7018" />
        

        <id>https://wg-eips.ritovision.com/3860/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:3860"
            label="EIP-3860" />
        

        
        

        
        <summary type="html">Limit the maximum size of initcode to 49152 and apply extra gas cost of 2 for every 32-byte chunk of initcode</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3860/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;We extend &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;170&#x2F;&quot;&gt;EIP-170&lt;&#x2F;a&gt; by introducing a maximum size limit for &lt;code&gt;initcode&lt;&#x2F;code&gt; (&lt;code&gt;MAX_INITCODE_SIZE = 2 * MAX_CODE_SIZE = 49152&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, we introduce a charge of &lt;code&gt;2&lt;&#x2F;code&gt; gas for every 32-byte chunk of &lt;code&gt;initcode&lt;&#x2F;code&gt; to represent the cost of jumpdest-analysis.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, the size limit results in the nice-to-have property that EVM code size, code offset (&lt;code&gt;PC&lt;&#x2F;code&gt;), and jump offset fits a 16-bit value.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;During contract creation the client has to perform jumpdest-analysis on the &lt;code&gt;initcode&lt;&#x2F;code&gt; prior to execution. The work performed scales linearly with the size of the &lt;code&gt;initcode&lt;&#x2F;code&gt;. This work currently is not metered, nor is there a protocol enforced upper bound for the size.&lt;&#x2F;p&gt;
&lt;p&gt;There are three costs charged today:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Cost for calldata aka &lt;code&gt;initcode&lt;&#x2F;code&gt;: 4 gas for a byte with the value of zero, and 16 gas otherwise.&lt;&#x2F;li&gt;
&lt;li&gt;Cost for the resulting deployed code: 200 gas per byte.&lt;&#x2F;li&gt;
&lt;li&gt;Cost of address calculation (hashing of code) in case of &lt;code&gt;CREATE2&lt;&#x2F;code&gt; only: 6 gas per word.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Only the first cost applies to &lt;code&gt;initcode&lt;&#x2F;code&gt;, but only in the case of contract creation transactions. For the case of &lt;code&gt;CREATE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;CREATE2&lt;&#x2F;code&gt; there is no such cost, and it is possible to programmatically generate variations of &lt;code&gt;initcode&lt;&#x2F;code&gt; in a relatively cheap manner. In the past it was possible to craft malicious &lt;code&gt;initcode&lt;&#x2F;code&gt; due to a vulnerability fixed in 2017 by geth 1.6.5.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, the lack of a limit has caused lengthy discussions for some EVM proposals, influencing the design, or even causing a delay or cancellation of a feature.&lt;&#x2F;p&gt;
&lt;p&gt;We are motivated by three reasons:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Ensuring &lt;code&gt;initcode&lt;&#x2F;code&gt; is fairly charged (most importantly cost is proportional to &lt;code&gt;initcode&lt;&#x2F;code&gt;&#x27;s length) to minimize the risks for the future.&lt;&#x2F;li&gt;
&lt;li&gt;To have a cost system which is extendable in the future.&lt;&#x2F;li&gt;
&lt;li&gt;To simplify EVM engines by the explicit limits (code size, code offsets (&lt;code&gt;PC&lt;&#x2F;code&gt;), and jump offsets fit 16-bits).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;INITCODE_WORD_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_INITCODE_SIZE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2 * MAX_CODE_SIZE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Where &lt;code&gt;MAX_CODE_SIZE&lt;&#x2F;code&gt; is defined by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;170&#x2F;&quot;&gt;EIP-170&lt;&#x2F;a&gt; as &lt;code&gt;24576&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We define &lt;code&gt;initcode_cost(initcode)&lt;&#x2F;code&gt; to equal &lt;code&gt;INITCODE_WORD_COST * ceil(len(initcode) &#x2F; 32)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rules&quot;&gt;Rules&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;If length of transaction data (&lt;code&gt;initcode&lt;&#x2F;code&gt;) in a create transaction exceeds &lt;code&gt;MAX_INITCODE_SIZE&lt;&#x2F;code&gt;, transaction is invalid. (&lt;em&gt;Note that this is similar to transactions considered invalid for not meeting the intrinsic gas cost requirement.&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;For a create transaction, extend the transaction data cost formula to include &lt;code&gt;initcode_cost(initcode)&lt;&#x2F;code&gt;. (&lt;em&gt;Note that this is included in transaction intrinsic cost, i.e. transaction with not enough gas to cover initcode cost is invalid.&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;If length of &lt;code&gt;initcode&lt;&#x2F;code&gt; to &lt;code&gt;CREATE&lt;&#x2F;code&gt; or &lt;code&gt;CREATE2&lt;&#x2F;code&gt; instructions exceeds &lt;code&gt;MAX_INITCODE_SIZE&lt;&#x2F;code&gt;, instruction execution exceptionally aborts (as if it runs out of gas).&lt;&#x2F;li&gt;
&lt;li&gt;For the &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; instructions charge an extra gas cost equaling to &lt;code&gt;initcode_cost(initcode)&lt;&#x2F;code&gt;. This cost is deducted before the calculation of the resulting contract address and the execution of &lt;code&gt;initcode&lt;&#x2F;code&gt;. (&lt;em&gt;Note that this means before or at the same time as the hashing cost is applied in &lt;code&gt;CREATE2&lt;&#x2F;code&gt;.&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gas-cost-constant&quot;&gt;Gas cost constant&lt;&#x2F;h3&gt;
&lt;p&gt;The value of &lt;code&gt;INITCODE_WORD_COST&lt;&#x2F;code&gt; is selected based on performance benchmarks of differing worst-cases per implementation. The baseline for the benchmarks is the performance of &lt;code&gt;KECCAK256&lt;&#x2F;code&gt; hashing in geth 1.10.9, which matches the 70 Mgas&#x2F;s gas limit target on a 4.0 GHz x86_64 CPU.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;EVM&lt;&#x2F;th&gt;&lt;th&gt;version&lt;&#x2F;th&gt;&lt;th&gt;MB&#x2F;s&lt;&#x2F;th&gt;&lt;th&gt;B&#x2F;CPUcycle&lt;&#x2F;th&gt;&lt;th&gt;CPUcycle&#x2F;B&lt;&#x2F;th&gt;&lt;th&gt;cost of 1 B&lt;&#x2F;th&gt;&lt;th&gt;cost of 32 B&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;geth&#x2F;KECCAK256&lt;&#x2F;td&gt;&lt;td&gt;1.10.9&lt;&#x2F;td&gt;&lt;td&gt;357&lt;&#x2F;td&gt;&lt;td&gt;1.8&lt;&#x2F;td&gt;&lt;td&gt;0.6&lt;&#x2F;td&gt;&lt;td&gt;0.2&lt;&#x2F;td&gt;&lt;td&gt;6.0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;geth&lt;&#x2F;td&gt;&lt;td&gt;1.10.9&lt;&#x2F;td&gt;&lt;td&gt;1091&lt;&#x2F;td&gt;&lt;td&gt;5.5&lt;&#x2F;td&gt;&lt;td&gt;0.2&lt;&#x2F;td&gt;&lt;td&gt;0.1&lt;&#x2F;td&gt;&lt;td&gt;2.0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;evmone&#x2F;Baseline&lt;&#x2F;td&gt;&lt;td&gt;0.8.2&lt;&#x2F;td&gt;&lt;td&gt;727&lt;&#x2F;td&gt;&lt;td&gt;3.7&lt;&#x2F;td&gt;&lt;td&gt;0.3&lt;&#x2F;td&gt;&lt;td&gt;0.1&lt;&#x2F;td&gt;&lt;td&gt;2.9&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;evmone&#x2F;Advanced&lt;&#x2F;td&gt;&lt;td&gt;0.8.2&lt;&#x2F;td&gt;&lt;td&gt;155&lt;&#x2F;td&gt;&lt;td&gt;0.8&lt;&#x2F;td&gt;&lt;td&gt;1.3&lt;&#x2F;td&gt;&lt;td&gt;0.4&lt;&#x2F;td&gt;&lt;td&gt;13.8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;gas-cost-per-word-32-byte-chunk&quot;&gt;Gas cost per word (32-byte chunk)&lt;&#x2F;h3&gt;
&lt;p&gt;We have chosen the cost of 2 gas per word based on Geth&#x27;s implementation and comparing with &lt;code&gt;KECCAK256&lt;&#x2F;code&gt; performance. This means the per byte cost is &lt;code&gt;0.0625&lt;&#x2F;code&gt;. While fractional gas costs are not permitted in the EVM, we can approximate it by charging per-word.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, calculating gas per word is compatible with the calculation of &lt;code&gt;CREATE2&lt;&#x2F;code&gt;&#x27;s &lt;em&gt;hashcost&lt;&#x2F;em&gt; of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1014&#x2F;&quot;&gt;EIP-1014&lt;&#x2F;a&gt;. Therefore, the same implementation may be used for &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; with different cost constants: before activation &lt;code&gt;0&lt;&#x2F;code&gt; for &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;6&lt;&#x2F;code&gt; for &lt;code&gt;CREATE2&lt;&#x2F;code&gt;, after activation &lt;code&gt;2&lt;&#x2F;code&gt; for &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;6 + 2&lt;&#x2F;code&gt; for &lt;code&gt;CREATE2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reason-for-size-limit-of-initcode&quot;&gt;Reason for size limit of initcode&lt;&#x2F;h3&gt;
&lt;p&gt;Estimating and creating worst case scenarios is easier with an upper bound in place, given one parameter for the search is greatly reduced. This allows for selecting a much more optimistic gas per byte.&lt;&#x2F;p&gt;
&lt;p&gt;Should there be no upper bound, the cost would need to be higher accounting for unknown unknowns. Given most &lt;em&gt;initcode&lt;&#x2F;em&gt; (&lt;em&gt;TODO: state maximum initcode size resulting in deployment seen on mainnet here&lt;&#x2F;em&gt;) does not exceed the proposed limit, penalising contracts by overly conservative costs seems unnecessary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;effect-of-size-limit-of-initcode&quot;&gt;Effect of size limit of initcode&lt;&#x2F;h3&gt;
&lt;p&gt;In most, if not all cases when a new contract is being created, the resulting runtime code is copied from the initcode itself. For the basic case the &lt;code&gt;2 * MAX_CODE_SIZE&lt;&#x2F;code&gt; limit allows &lt;code&gt;MAX_CODE_SIZE&lt;&#x2F;code&gt; for runtime code and another &lt;code&gt;MAX_CODE_SIZE&lt;&#x2F;code&gt; for contract constructor code. However, the limit may have practical implications for cases where multiple contracts are deployed in a single create transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initcode-cost-for-create-transaction&quot;&gt;Initcode cost for create transaction&lt;&#x2F;h3&gt;
&lt;p&gt;The initcode cost for create transaction data (0.0625 gas per byte) is negligible compared to the transaction data cost (4 or 16 gas per byte). Despite that, we decided to include it in the specification for consistency, and more importantly for forward compatibility.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-report-initcode-limit-violation&quot;&gt;How to report initcode limit violation?&lt;&#x2F;h3&gt;
&lt;p&gt;We specified that initcode size limit violation for &lt;code&gt;CREATE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;CREATE2&lt;&#x2F;code&gt; results in exceptional abort of the execution. This places it in the group of early out-of-gas checks, including: stack underflow, memory expansion, static call violation, initcode hashing cost, and initcode cost introduced by this EIP. They precede the later &quot;light&quot; checks: call depth and balance. The choice gives consistency to the order of checks and lowers implementation complexity (out-of-gas checks can be performed in any order).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP requires a &quot;network upgrade&quot;, since it modifies consensus rules.&lt;&#x2F;p&gt;
&lt;p&gt;Already deployed contracts should not be affected, but certain transactions (with &lt;code&gt;initcode&lt;&#x2F;code&gt; beyond the proposed limit) would still be includable in a block, but result in an exceptional abort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tests should include the following cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Creation transaction with gas limit enough to cover initcode cost&lt;&#x2F;li&gt;
&lt;li&gt;Creation transaction with gas limit enough to cover intrinsic cost except initcode cost&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CREATE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;CREATE2&lt;&#x2F;code&gt;&#x2F;creation transaction with &lt;code&gt;len(initcode)&lt;&#x2F;code&gt; at &lt;code&gt;MAX_INITCODE_SIZE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CREATE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;CREATE2&lt;&#x2F;code&gt;&#x2F;creation transaction with &lt;code&gt;len(initcode)&lt;&#x2F;code&gt; at &lt;code&gt;MAX_INITCODE_SIZE+1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;For client implementations, this EIP makes attacks based on jumpdest-analysis less problematic, so should increase the robustness of clients.&lt;&#x2F;p&gt;
&lt;p&gt;For layer 2, this EIP introduces failure-modes where there previously were none. There &lt;em&gt;could&lt;&#x2F;em&gt; exist factory-contracts which deploy multi-level contract hierarchies, such that the code for multiple contracts are included in the initcode of the first contract. The author(s) of this EIP are not aware of any such contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Currently, on London, with &lt;code&gt;30M&lt;&#x2F;code&gt; gas limit, it would be possible to trigger jumpdest-analysis of a total &lt;code&gt;~1.3GB&lt;&#x2F;code&gt; of initcode. With this EIP, the cost for such an attack would increase by roughly &lt;code&gt;80M&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Warm COINBASE</title>
        <published>2021-07-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>William Morriss</name><uri>https://github.com/wjmelements</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3651/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3651-warm-coinbase/6640" />
        

        <id>https://wg-eips.ritovision.com/3651/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:3651"
            label="EIP-3651" />
        

        
        

        
        <summary type="html">Starts the `COINBASE` address warm</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3651/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;COINBASE&lt;&#x2F;code&gt; address shall be warm at the start of transaction execution, in accordance with the actual cost of reading that account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Direct &lt;code&gt;COINBASE&lt;&#x2F;code&gt; payments are becoming increasingly popular because they allow conditional payments, which provide benefits such as implicit cancellation of transactions that would revert.
But accessing &lt;code&gt;COINBASE&lt;&#x2F;code&gt; is overpriced; the address is initially cold under the access list framework introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt;.
This gas cost mismatch can incentivize alternative payments besides ETH, such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, but ETH should be the primary means of paying for transactions on Ethereum.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;At the start of transaction execution, &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; shall be initialized to also include the address returned by &lt;code&gt;COINBASE&lt;&#x2F;code&gt; (&lt;code&gt;0x41&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The addresses currently initialized warm are the addresses that should already be loaded at the start of transaction validation.
The &lt;code&gt;ORIGIN&lt;&#x2F;code&gt; address is always loaded to check its balance against the gas limit and the gas price.
The &lt;code&gt;tx.to&lt;&#x2F;code&gt; address is always loaded to begin execution.
The &lt;code&gt;COINBASE&lt;&#x2F;code&gt; address should also be always be loaded because it receives the block reward and the transaction fees.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no known backward compatibility issues presented by this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no known security considerations introduced by this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>T-REX - Token for Regulated EXchanges</title>
        <published>2021-07-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Joachim Lebrun</name><uri>https://github.com/Joachim-Lebrun</uri>
	</author>
	
	<author>
		<name>Tony Malghem</name><uri>https://github.com/TonyMalghem</uri>
	</author>
	
	<author>
		<name>Kevin Thizy</name><uri>https://github.com/Nakasar</uri>
	</author>
	
	<author>
		<name>Luc Falempin</name><uri>https://github.com/lfalempin</uri>
	</author>
	
	<author>
		<name>Adam Boudjemaa</name><uri>https://github.com/Aboudjem</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3643/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3643-proposition-of-the-t-rex-token-standard-for-securities/6844" />
        

        <id>https://wg-eips.ritovision.com/3643/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:3643"
            label="ERC-3643" />
        

        
        

        
        <summary type="html">An institutional grade security token contract that provides interfaces for the management and compliant transfer of security tokens.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3643/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The T-REX token is an institutional grade security token standard. This standard provides a library of interfaces for the management and compliant transfer of security tokens, using an automated onchain validator system leveraging onchain identities for eligibility checks.&lt;&#x2F;p&gt;
&lt;p&gt;The standard defines several interfaces that are described hereunder:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Token&lt;&#x2F;li&gt;
&lt;li&gt;Identity Registry&lt;&#x2F;li&gt;
&lt;li&gt;Identity Registry Storage&lt;&#x2F;li&gt;
&lt;li&gt;Compliance&lt;&#x2F;li&gt;
&lt;li&gt;Trusted Issuers Registry&lt;&#x2F;li&gt;
&lt;li&gt;Claim Topics Registry&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The advent of blockchain technology has brought about a new era of efficiency, accessibility, and liquidity in the world of asset transfer. This is particularly evident in the realm of cryptocurrencies, where users can transfer token ownership peer-to-peer without intermediaries. However, when it comes to tokenized securities or security tokens, the situation is more complex due to the need for compliance with securities laws. These tokens cannot be permissionless like utility tokens; they must be permissioned to track ownership and ensure that only eligible investors can hold tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The existing Ethereum protocol, while powerful and versatile, does not fully address the unique challenges posed by security tokens. There is a need for a standard that supports compliant issuance and management of permissioned tokens, suitable for representing a wide range of asset classes, including small businesses and real estate.&lt;&#x2F;p&gt;
&lt;p&gt;The proposed &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;&quot;&gt;ERC-3643&lt;&#x2F;a&gt; standard is motivated by this need. It aims to provide a comprehensive framework for managing the lifecycle of security tokens, from issuance to transfers between eligible investors, while enforcing compliance rules at every stage. The standard also supports additional features such as token pausing and freezing, which can be used to manage the token in response to regulatory requirements or changes in the status of the token or its holders.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, the standard is designed to work in conjunction with an on-chain Identity system, allowing for the validation of the identities and credentials of investors through signed attestations issued by trusted claim issuers. This ensures compliance with legal and regulatory requirements for the trading of security tokens.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, the motivation behind the proposed standard is to bring the benefits of blockchain technology to the world of securities, while ensuring compliance with existing securities laws. It aims to provide a robust, flexible, and efficient framework for the issuance and management of security tokens, thereby accelerating the evolution of capital markets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The proposed standard has the following requirements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatible.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be used in combination with an onchain Identity system&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be able to apply any rule of compliance that is required by the regulator or by the token issuer (about the factors of eligibility of an identity or about the rules of the token itself)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; have a standard interface to pre-check if a transfer is going to pass or fail before sending it to the blockchain&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; have a recovery system in case an investor loses access to his private key&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be able to freeze tokens on the wallet of investors if needed, partially or totally&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; have the possibility to pause the token&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be able to mint and burn tokens&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; define an Agent role and an Owner (token issuer) role&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be able to force transfers from an Agent wallet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be able to issue transactions in batch (to save gas and to have all the transactions performed in the same block)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While this standard is backwards compatible with ERC-20 and all ERC-20 functions can be called on an ERC-3643 token, the implementation of these functions differs due to the permissioned nature of ERC-3643. Each token transfer under this standard involves a compliance check to validate the transfer and the eligibility of the stakeholder’s identities.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;agent-role-interface&quot;&gt;Agent Role Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The standard defines an Agent role, which is crucial for managing access to various functions of the smart contracts. The interface for the Agent role is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IAgentRole&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AgentAdded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _agent&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AgentRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _agent&lt;&#x2F;span&gt;&lt;span&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&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; setters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addAgent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _agent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeAgent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _agent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isAgent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _agent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;IAgentRole&lt;&#x2F;code&gt; interface allows for the addition and removal of agents, as well as checking if an address is an agent. In this standard, it is the owner role, as defined by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;173&#x2F;&quot;&gt;ERC-173&lt;&#x2F;a&gt;, that has the responsibility of appointing and removing agents. Any contract that fulfills the role of a Token contract or an Identity Registry within the context of this standard must be compatible with the &lt;code&gt;IAgentRole&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;main-functions&quot;&gt;Main functions&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;transfer&quot;&gt;Transfer&lt;&#x2F;h4&gt;
&lt;p&gt;To be able to perform a transfer on T-REX you need to fulfill several conditions :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The sender &lt;strong&gt;MUST&lt;&#x2F;strong&gt; hold enough free balance (total balance - frozen tokens, if any)&lt;&#x2F;li&gt;
&lt;li&gt;The receiver &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be whitelisted on the Identity Registry and verified (hold the necessary claims on his onchain Identity)&lt;&#x2F;li&gt;
&lt;li&gt;The sender&#x27;s wallet &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be frozen&lt;&#x2F;li&gt;
&lt;li&gt;The receiver&#x27;s wallet &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be frozen&lt;&#x2F;li&gt;
&lt;li&gt;The token &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be paused&lt;&#x2F;li&gt;
&lt;li&gt;The transfer &lt;strong&gt;MUST&lt;&#x2F;strong&gt; respect all the rules of compliance defined in the Compliance smart contract (canTransfer needs to return TRUE)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here is an example of &lt;code&gt;transfer&lt;&#x2F;code&gt; function implementation :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; whenNotPaused&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;_frozen&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;_frozen&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC-3643: Frozen wallet&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_amount &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_frozenTokens&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC-3643: Insufficient Balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; _tokenIdentityRegistry&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isVerified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC-3643: Invalid identity&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; _tokenCompliance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;canTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC-3643: Compliance failure&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _amount&lt;&#x2F;span&gt;&lt;span&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&gt;        _tokenCompliance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;transferFrom&lt;&#x2F;code&gt; function works the same way while the &lt;code&gt;mint&lt;&#x2F;code&gt; function and the &lt;code&gt;forcedTransfer&lt;&#x2F;code&gt; function only require the receiver to be whitelisted and verified on the Identity Registry (they bypass the compliance rules). The &lt;code&gt;burn&lt;&#x2F;code&gt; function bypasses all checks on eligibility.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;isverified&quot;&gt;isVerified&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;isVerified&lt;&#x2F;code&gt; function is called from within the transfer functions &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;mint&lt;&#x2F;code&gt; and
&lt;code&gt;forcedTransfer&lt;&#x2F;code&gt; to instruct the &lt;code&gt;Identity Registry&lt;&#x2F;code&gt; to check if the receiver is a valid investor, i.e. if his
wallet address is in the &lt;code&gt;Identity Registry&lt;&#x2F;code&gt; of the token, and if the &lt;code&gt;Identity&lt;&#x2F;code&gt;contract linked to his wallet
contains the claims (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IERC735.sol&quot;&gt;Claim Holder&lt;&#x2F;a&gt;) required in the &lt;code&gt;Claim Topics Registry&lt;&#x2F;code&gt; and
if these claims are signed by an authorized Claim Issuer as required in the &lt;code&gt;Trusted Issuers Registry&lt;&#x2F;code&gt;.
If all the requirements are fulfilled, the &lt;code&gt;isVerified&lt;&#x2F;code&gt; function returns &lt;code&gt;TRUE&lt;&#x2F;code&gt;, otherwise it returns &lt;code&gt;FALSE&lt;&#x2F;code&gt;. An
implementation of this function can be found on the T-REX repository of Tokeny.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cantransfer&quot;&gt;canTransfer&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;canTransfer&lt;&#x2F;code&gt; function is also called from within transfer functions. This function checks if the transfer is compliant with global compliance rules applied to the token, in opposition with &lt;code&gt;isVerified&lt;&#x2F;code&gt; that only checks the eligibility of an investor to hold and receive tokens, the &lt;code&gt;canTransfer&lt;&#x2F;code&gt; function is looking at global compliance rules, e.g. check if the transfer is compliant in the case there is a fixed maximum number of token holders to respect (can be a limited number of holders per country as well), check if the transfer respects rules setting a maximum amount of tokens per investor, ...
If all the requirements are fulfilled, the &lt;code&gt;canTransfer&lt;&#x2F;code&gt; function will return &lt;code&gt;TRUE&lt;&#x2F;code&gt; otherwise it will return
&lt;code&gt;FALSE&lt;&#x2F;code&gt; and the transfer will not be allowed to happen. An implementation of this function can be found on the T-REX
repository of Tokeny.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;other-functions&quot;&gt;Other functions&lt;&#x2F;h4&gt;
&lt;p&gt;Description of other functions of the ERC-3643 can be found in the &lt;code&gt;interfaces&lt;&#x2F;code&gt; folder. An implementation of the
ERC-3643 suite of smart contracts can be found on the T-REX repository of Tokeny.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;token-interface&quot;&gt;Token interface&lt;&#x2F;h3&gt;
&lt;p&gt;ERC-3643 permissioned tokens build upon the standard ERC-20 structure, but with additional functions to ensure compliance in the transactions of the security tokens. The functions &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; are implemented in a conditional way, allowing them to proceed with a transfer only if the transaction is valid. The permissioned tokens are allowed to be transferred only to validated counterparties, in order to avoid tokens being held in wallets&#x2F;Identity contracts of ineligible&#x2F;unauthorized investors. The ERC-3643 standard also supports the recovery of security tokens in case an investor loses access to their wallet private key. A history of recovered tokens is maintained on the blockchain for transparency reasons.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-3643 tokens implement a range of additional functions to enable the owner or their appointed agents to manage supply, transfer rules, lockups, and any other requirements in the management of a security. The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of appointing agents. Any contract that fulfills the role of a Token contract within the context of this standard must be compatible with the &lt;code&gt;IAgentRole&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;IERC3643.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3643&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC20&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; UpdatedTokenInformation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newName&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newSymbol&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newDecimals&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newVersion&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newOnchainID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRegistryAdded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _identityRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ComplianceAdded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _compliance&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RecoverySuccess&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _lostWallet&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newWallet&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _investorOnchainID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddressFrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _isFrozen&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokensFrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokensUnfrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Paused&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Unpaused&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onchainID&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; identityRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IIdentityRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; compliance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ICompliance&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; paused&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isFrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getFrozenTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; setters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setName&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setSymbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setOnchainID&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _onchainID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; pause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unpause&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setAddressFrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _freeze&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; freezePartialTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unfreezePartialTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setIdentityRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identityRegistry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setCompliance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _compliance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; transfer actions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; forcedTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; recoveryAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _lostWallet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newWallet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _investorOnchainID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; batch functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchForcedTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toList&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchSetAddressFrozen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _freeze&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchFreezePartialTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchUnfreezePartialTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;identity-registry-interface&quot;&gt;Identity Registry Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The Identity Registry is linked to storage that contains a dynamic whitelist of identities. It establishes the link between a wallet address, an Identity smart contract, and a country code corresponding to the investor&#x27;s country of residence. This country code is set in accordance with the ISO-3166 standard. The Identity Registry also includes a function called &lt;code&gt;isVerified()&lt;&#x2F;code&gt;, which returns a status based on the validity of claims (as per the security token requirements) in the user’s Identity contract.&lt;&#x2F;p&gt;
&lt;p&gt;The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of appointing agents. Any contract that fulfills the role of an Identity Registry within the context of this standard must be compatible with the &lt;code&gt;IAgentRole&lt;&#x2F;code&gt; interface. The Identity Registry is managed by the agent wallet(s), meaning only the agent(s) can add or remove identities in the registry. Note that the agent role on the Identity Registry is set by the owner, therefore the owner could set themselves as the agent if they want to maintain full control. There is a specific identity registry for each security token.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;IIdentityRegistry.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IClaimIssuer.sol&quot;&gt;&lt;code&gt;IClaimIssuer&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IIdentity.sol&quot;&gt;&lt;code&gt;IIdentity&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; are needed in this interface as they are required for the Identity eligibility checks.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IIdentityRegistry&lt;&#x2F;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimTopicsRegistrySet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopicsRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityStorageSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityStorage&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TrustedIssuersRegistrySet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; trustedIssuersRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRegistered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldIdentity&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newIdentity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CountryUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; country&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; identity registry getters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; identityStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IIdentityRegistryStorage&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; issuersRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;ITrustedIssuersRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; topicsRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimTopicsRegistry&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;identity registry setters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setIdentityRegistryStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identityRegistryStorage&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setClaimTopicsRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopicsRegistry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTrustedIssuersRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _trustedIssuersRegistry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; registry actions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; registerIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identity&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _country&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; deleteIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateCountry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _country&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identity&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; batchRegisterIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IIdentity&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identities&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _countries&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; registry consultation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; contains&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isVerified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; investorCountry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint16&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;identity-registry-storage-interface&quot;&gt;Identity Registry Storage Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The Identity Registry Storage stores the identity addresses of all the authorized investors in the security token(s) linked to the storage contract. These are all identities of investors who have been authorized to hold the token(s) after having gone through the appropriate KYC and eligibility checks. The Identity Registry Storage can be bound to one or several Identity Registry contract(s). The goal of the Identity Registry storage is to separate the Identity Registry functions and specifications from its storage. This way, it is possible to keep one single Identity Registry contract per token, with its own Trusted Issuers Registry and Claim Topics Registry, but with a shared whitelist of investors used by the &lt;code&gt;isVerifed()&lt;&#x2F;code&gt; function implemented in the Identity Registries to check the eligibility of the receiver in a transfer transaction.&lt;&#x2F;p&gt;
&lt;p&gt;The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of appointing agents(in this case through the &lt;code&gt;bindIdentityRegistry&lt;&#x2F;code&gt; function). Any contract that fulfills the role of an Identity Registry Storage within the context of this standard must be compatible with the &lt;code&gt;IAgentRole&lt;&#x2F;code&gt; interface. The Identity Registry Storage is managed by the agent addresses (i.e. the bound Identity Registries), meaning only the agent(s) can add or remove identities in the registry. Note that the agent role on the Identity Registry Storage is set by the owner, therefore the owner could set themselves as the agent if they want to modify the storage manually. Otherwise it is the bound Identity Registries that are using the agent role to write in the Identity Registry Storage.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;IIdentityRegistryStorage.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IIdentityRegistryStorage&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityStored&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityUnstored&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityModified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; oldIdentity&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newIdentity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; CountryModified&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; investorAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; country&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRegistryBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityRegistry&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IdentityRegistryUnbound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; identityRegistry&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; storage related functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; storedIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IIdentity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; storedInvestorCountry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint16&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addIdentityToStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identity&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _country&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeIdentityFromStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; modifyStoredInvestorCountry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint16&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _country&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; modifyStoredIdentity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _userAddress&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; IIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identity&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; role setter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bindIdentityRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identityRegistry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unbindIdentityRegistry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _identityRegistry&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getter for bound IdentityRegistry role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; linkedIdentityRegistries&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;compliance-interface&quot;&gt;Compliance Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The Compliance contract is used to set the rules of the offering itself and ensures these rules are respected during the whole lifecycle of the token. For example, the Compliance contract will define the maximum amount of investors per country, the maximum amount of tokens per investor, and the accepted countries for the circulation of the token (using the country code corresponding to each investor in the Identity Registry). The Compliance smart contract can be either “tailor-made”, following the legal requirements of the token issuer, or can be deployed under a generic modular form, which can then add and remove external compliance &lt;code&gt;Modules&lt;&#x2F;code&gt; to fit the legal requirements of the token in the same way as a custom &quot;tailor-made&quot; contract would.&lt;&#x2F;p&gt;
&lt;p&gt;This contract is triggered at every transaction by the Token and returns &lt;code&gt;TRUE&lt;&#x2F;code&gt; if the transaction is compliant with the rules of the offering and &lt;code&gt;FALSE&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of setting the Compliance parameters and binding the Compliance to a Token contract.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;ICompliance.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ICompliance&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TokenUnbound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; initialization of the compliance contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bindToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unbindToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check the parameters of the compliance contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTokenBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTokenBound&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; compliance check and state update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; created&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; destroyed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;trusted-issuer-s-registry-interface&quot;&gt;Trusted Issuer&#x27;s Registry Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The Trusted Issuer&#x27;s Registry stores the contract addresses (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IClaimIssuer.sol&quot;&gt;IClaimIssuer&lt;&#x2F;a&gt;) of all the trusted claim issuers for a specific security token. The Identity contract (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IIdentity.sol&quot;&gt;IIdentity&lt;&#x2F;a&gt;) of token owners (the investors) must have claims signed by the claim issuers stored in this smart contract in order to be able to hold the token.&lt;&#x2F;p&gt;
&lt;p&gt;The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of managing this registry as per their requirements. This includes the ability to add, remove, and update the list of Trusted Issuers.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;ITrustedIssuersRegistry.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ITrustedIssuersRegistry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TrustedIssuerAdded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopics&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TrustedIssuerRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; trustedIssuer&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimTopicsUpdated&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopics&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; setters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addTrustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopics&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeTrustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateIssuerClaimTopics&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopics&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTrustedIssuers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTrustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _issuer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTrustedIssuerClaimTopics&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _trustedIssuer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getTrustedIssuersForClaimTopic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;IClaimIssuer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hasClaimTopic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _issuer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;claim-topics-registry-interface&quot;&gt;Claim Topics Registry Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The Claim Topics Registry stores all the trusted claim topics for the security token. The Identity contract (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IIdentity.sol&quot;&gt;IIdentity&lt;&#x2F;a&gt;) of token owners must contain claims of the claim topics stored in this smart contract.&lt;&#x2F;p&gt;
&lt;p&gt;The standard relies on ERC-173 to define contract ownership, with the owner having the responsibility of managing this registry as per their requirements. This includes the ability to add and remove required Claim Topics.&lt;&#x2F;p&gt;
&lt;p&gt;A detailed description of the functions can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;IClaimTopicsRegistry.sol&quot;&gt;interfaces folder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IClaimTopicsRegistry&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimTopicAdded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopic&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ClaimTopicRemoved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; claimTopic&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; setters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addClaimTopic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; removeClaimTopic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _claimTopic&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; getter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getClaimTopics&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;transfer-restrictions&quot;&gt;Transfer Restrictions&lt;&#x2F;h3&gt;
&lt;p&gt;Transfers of securities can fail for a variety of reasons. This is in direct contrast to utility tokens, which generally only require the sender to have a sufficient balance. These conditions can be related to the status of an investor’s wallet, the identity of the sender and receiver of the securities (i.e., whether they have been through a KYC process, whether they are accredited or an affiliate of the issuer) or for reasons unrelated to the specific transfer but instead set at the token level (i.e., the token contract enforces a maximum number of investors or a cap on the percentage held by any single investor). For ERC-20 tokens, the &lt;code&gt;balanceOf&lt;&#x2F;code&gt; and &lt;code&gt;allowance&lt;&#x2F;code&gt; functions provide a way to check that a transfer is likely to succeed before executing the transfer, which can be executed both on-chain and off-chain. For tokens representing securities, the T-REX standard introduces a function &lt;code&gt;canTransfer&lt;&#x2F;code&gt; which provides a more general-purpose way to achieve this. I.e., when the reasons for failure are related to the compliance rules of the token and a function &lt;code&gt;isVerified&lt;&#x2F;code&gt; which allows checking the eligibility status of the identity of the investor. Transfers can also fail if the address of the sender and&#x2F;or receiver is frozen, or if the free balance of the sender (total balance - frozen tokens) is lower than the amount to transfer. Ultimately, the transfer could be blocked if the token is &lt;code&gt;paused&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;identity-management&quot;&gt;Identity Management&lt;&#x2F;h3&gt;
&lt;p&gt;Security and compliance of transfers are enforced through the management of on-chain identities. These include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Identity contract: A unique identifier for each investor, which is used to manage their identity and claims.&lt;&#x2F;li&gt;
&lt;li&gt;Claim: Signed attestations issued by a trusted claim issuer that confirm certain attributes or qualifications of the token holders, such as their identity, location, investor status, or KYC&#x2F;AML clearance.&lt;&#x2F;li&gt;
&lt;li&gt;Identity Storage&#x2F;Registry: A storage system for all Identity contracts and their associated wallets, which is used to
verify the eligibility of investors during transfers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;token-lifecycle-management&quot;&gt;Token Lifecycle Management&lt;&#x2F;h3&gt;
&lt;p&gt;The T-REX standard provides a comprehensive framework for managing the lifecycle of security tokens. This includes the issuance of tokens, transfers between eligible investors, and the enforcement of compliance rules at every stage of the token&#x27;s lifecycle. The standard also supports additional features such as token pausing and freezing, which can be used to manage the token in response to regulatory requirements or changes in the status of the token or its holders.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;additional-compliance-rules&quot;&gt;Additional Compliance Rules&lt;&#x2F;h3&gt;
&lt;p&gt;The T-REX standard supports the implementation of additional compliance rules through modular compliance. These modules can be used to enforce a wide range of rules and restrictions, such as caps on the number of investors or the percentage of tokens held by a single investor, restrictions on transfers between certain types of investors, and more. This flexibility allows issuers to tailor the compliance rules of their tokens to their specific needs and regulatory environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inclusion-of-agent-related-functions&quot;&gt;Inclusion of Agent-Related Functions&lt;&#x2F;h3&gt;
&lt;p&gt;The inclusion of Agent-scoped functions within the standard interfaces is deliberate. The intent is to accommodate secure and adaptable token management practices that surpass the capabilities of EOA management. We envision scenarios where the agent role is fulfilled by automated systems or smart contracts, capable of programmatically executing operational functions like minting, burning, and freezing in response to specified criteria or regulatory triggers. For example, a smart contract might automatically burn tokens to align with redemption requests in an open-ended fund, or freeze tokens associated with wallets engaged in fraudulent activities.&lt;&#x2F;p&gt;
&lt;p&gt;Consequently, these functions are standardized to provide a uniform interface for various automated systems interacting with different ERC-3643 tokens, allowing for standardized tooling and interfaces that work across the entire ecosystem. This approach ensures that ERC-3643 remains flexible, future-proof, and capable of supporting a wide array of operational models.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;T-REX tokens should be backwards compatible with ERC-20 and ERC-173
and should be able to interact with a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IERC735.sol&quot;&gt;Claim Holder contract&lt;&#x2F;a&gt; to validate
the claims linked to an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3643&#x2F;.&#x2F;assets&#x2F;ONCHAINID&#x2F;IIdentity.sol&quot;&gt;Identity contract&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This specification has been audited by Kapersky and Hacken, and no notable security considerations were found.
While the audits were primarily focused on the specific implementation by Tokeny, they also challenged and validated the core principles of the T-REX standard. The auditing teams approval of these principles provides assurance that the standard itself is robust and does not present any significant security concerns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Reject transactions from senders with deployed code</title>
        <published>2021-06-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	<author>
		<name>Dmitry Khovratovich</name><uri>https://github.com/khovratovich</uri>
	</author>
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3607/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/3608" />
        

        <id>https://wg-eips.ritovision.com/3607/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:3607"
            label="EIP-3607" />
        

        
        

        
        <summary type="html">Do not allow transactions for which `tx.sender` has any code deployed.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3607/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum addresses are currently only 160 bits long. This means it is possible to create a collision between a contract account and an Externally Owned Account (EOA) using an estimated &lt;code&gt;2**80&lt;&#x2F;code&gt; computing operations, which is feasible now given a large budget (ca. 10 billion USD). The fix in this EIP prevents the worst possible attack, where a safe looking contract (e.g. a token wrapper or an AMM-type contract) is deployed to attract user funds, which can then be spent using the EOA key for the same address. The fix is to never allow to use an address that already has code deployed as an EOA address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;generating-address-collisions&quot;&gt;Generating address collisions&lt;&#x2F;h3&gt;
&lt;p&gt;By creating keys for &lt;code&gt;2**80&lt;&#x2F;code&gt; EOAs and simulating the deployment of &lt;code&gt;2**80&lt;&#x2F;code&gt; contracts from these EOAs (one each), one expects to find about one collision where an EOA has the same address as one contract.&lt;&#x2F;p&gt;
&lt;p&gt;This very simple form of the attack requires the storage of &lt;code&gt;2**80&lt;&#x2F;code&gt; addresses, which is a practical barrier: It would require &lt;code&gt;2.4*10**25&lt;&#x2F;code&gt; bytes of memory (24 Yottabyte). However, there are cycle finding algorithms that can perform the collision search without requiring large amounts of storage. An estimate for the complexity has been made &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;Vzhp5YJyTT-LhWm_s0JQpA&quot;&gt;here&lt;&#x2F;a&gt;. We estimate that a collision between a contract and an EOA could be found in about one year with an investment of ca. US$10 billion in hardware and electricity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;background&quot;&gt;Background&lt;&#x2F;h3&gt;
&lt;p&gt;There is currently a discussion to move to 256-bit addresses on Ethereum, which would increase collision resistance to a complexity of &lt;code&gt;2**128&lt;&#x2F;code&gt; which is currently thought infeasible for the foreseeable future. However, with 160 bit addresses, the collision problem can be effectively solved now, as demonstrated above.&lt;&#x2F;p&gt;
&lt;p&gt;Most attacks that can occur via address collisions are quite impractical: They involve users sending funds to an address before a contract is deployed. This is a very rare application in practice and users can easily circumvent the attack by never sending funds to a contract until it has been safely deployed with enough confirmations.&lt;&#x2F;p&gt;
&lt;p&gt;However, the yellow paper does not explicitly specify how a client should handle the case where a transaction is sent from an account that already has contract code deployed; presumably because this was considered infeasible at the time. The assumption is that most client would allow this transaction in their current state.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP is to specify this behaviour to always forbid such transactions. This fixes most realistic or serious attacks due to address collisions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Any transaction where &lt;code&gt;tx.sender&lt;&#x2F;code&gt; has a &lt;code&gt;CODEHASH != EMPTYCODEHASH&lt;&#x2F;code&gt; MUST be rejected as invalid, where &lt;code&gt;EMPTYCODEHASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470&lt;&#x2F;code&gt;.
The invalid transaction MUST be rejected by the client and not be included in a block.
A block containing such a transaction MUST be considered invalid.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;We note that it was always expected that a contract account&#x27;s behaviour is constrained by the code in that contract -- which means that the account&#x27;s funds should not suddenly be spendable by some private key. It was just implicitly assumed in the past that a 160 bit address length is enough to provide collision resistance, and thus that this case could never occur. In that sense, this EIP should be seen as a clarification of protocol behaviour in a previously undefined case rather than an explicit upgrade of consensus rules.&lt;&#x2F;p&gt;
&lt;p&gt;This does not exclude all possible attack vectors, only the most serious one. Further possible attack vectors via address collisions between contracts and EOAs are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;An attacker can convince a user to send funds to an account before it is deployed. Some applications require this behaviour (e.g. state channels).&lt;&#x2F;li&gt;
&lt;li&gt;A chain reorg can happen after a contract is deployed. If the reorg removes the contract deployment transaction the funds can still be accessed using the private key.&lt;&#x2F;li&gt;
&lt;li&gt;A contract can self destruct, with the stated intention that ERC20s (or other tokens) in the contract would be burned. However, they can now be accessed by a key for that address.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All these scenarios are much harder to exploit for an attacker, and likely have much lower yield making the attacks unlikely to be economically viable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;It is unlikely that an attack like this has already occurred on the Ethereum mainnet, or we would very likely have heard of it. It is inconceivable that someone would use this as a &quot;feature&quot; to make a contract an EOA at the same time, when they could simply do this by adding some methods to the contract instead of spending billions on building hardware to find hash collisions.&lt;&#x2F;p&gt;
&lt;p&gt;Private networks may have deployed contracts which also work as EOAs at genesis and should check that this upgrade does not impact their workflows.&lt;&#x2F;p&gt;
&lt;p&gt;Clients might choose to disable this rule for RPC calls like &lt;code&gt;eth_call&lt;&#x2F;code&gt; and &lt;code&gt;eth_estimateGas&lt;&#x2F;code&gt; as some Multi-Sig contracts use these calls to create transactions as if they originated from the multisig contract itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Given a genesis allocation of&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Address: 0x71562b71999873DB5b286dF957af199Ec94617F7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Balance: 1000000000000000000 &#x2F;&#x2F; 1 ether&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce:   0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Code:    0xB0B0FACE&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every transaction sent by the private key corresponding to &lt;code&gt;0x715656...&lt;&#x2F;code&gt; (
&lt;code&gt;b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291&lt;&#x2F;code&gt;) should be rejected.
These transaction must be rejected and not included in a block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The following check must be added to the state transition checks after checking that the nonce of the sender is correct.
The sender is the address recovered from the signature of the transaction.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; Make sure the sender is an EOA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Set ch to the CodeHash of the sender account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if ch is not equal to EmptyCodeHash then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	return ErrSenderNoEOA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A diff to implement EIP-3607 in go-ethereum can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3607&#x2F;.&#x2F;assets&#x2F;geth.diff&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is a strict security upgrade: It simply makes some transactions that were formerly valid now invalid. There is no legitimate use for such transactions, so there should be no security downsides.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP can be implemented as a soft fork because the new validity rules are a strict superset of the previous validity rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Difficulty Bomb Delay to December 2021</title>
        <published>2021-05-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>James Hancock</name><uri>https://github.com/madeoftin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3554/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3554-ice-age-delay-targeting-december-2021/6188" />
        

        <id>https://wg-eips.ritovision.com/3554/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:3554"
            label="EIP-3554" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3554/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Delays the difficulty bomb to show effect the first week of December 2021.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 9,700,000 blocks later than the actual block number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Targeting for the Shanghai upgrade and&#x2F;or the Merge to occur before December 2021. Either the bomb can be readjusted at that time, or removed all together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fake_block_number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9_700_000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The following script predicts a .1 second delay to blocktime the first week of december and a 1 second delay by the end of the month. This gives reason to address because the effect will be seen, but not so much urgency we don&#x27;t have space to work around if needed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; predict_diff_bomb_effect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;current_blknum&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; current_difficulty&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block_adjustment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; months&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Predicts the effect on block time (as a ratio) in a specified amount of months in the future.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Vars used in last prediction:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    current_blknum = 12382958&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    current_difficulty = 7393633000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    block adjustment = 9700000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    months = 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blocks_per_month&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;86400&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    future_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; current_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; blocks_per_month&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; months&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    diff_adjustment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; **&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;future_blknum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; block_adjustment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;    diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; diff_adjustment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; current_difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2048&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; diff_adjust_coeff&lt;&#x2F;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;diff_adjust_coeff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; predict_diff_bomb_effect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12382958&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7393633000000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9700000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No known backward compatibility issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Misjudging the effects of the difficulty can mean longer blocktimes than anticipated until a hardfork is released. Wild shifts in difficulty can affect this number severely. Also, gradual changes in blocktimes due to longer-term adjustments in difficulty can affect the timing of difficulty bomb epochs. This affects the usability of the network but unlikely to have security ramifications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Reduction in refunds</title>
        <published>2021-04-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Martin Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3529/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3529-reduction-in-refunds-alternative-to-eip-3298-and-3403-that-better-preserves-existing-clearing-incentives/6097" />
        

        <id>https://wg-eips.ritovision.com/3529/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:3529"
            label="EIP-3529" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3529/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Remove gas refunds for &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;, and reduce gas refunds for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; to a lower level where the refunds are still substantial, but they are no longer high enough for current &quot;exploits&quot; of the refund mechanism to be viable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Gas refunds for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; and &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; were originally introduced to motivate application developers to write applications that practice &quot;good state hygiene&quot;, clearing storage slots and contracts that are no longer needed. However, the benefits of this technique have proven to be far lower than anticipated, and gas refunds have had multiple unexpected harmful consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Refunds give rise to GasToken. GasToken has benefits in moving gas space from low-fee periods to high-fee periods, but it also has downsides to the network, particularly in exacerbating state size (as state slots are effectively used as a &quot;battery&quot; to save up gas) and inefficiently clogging blockchain gas usage&lt;&#x2F;li&gt;
&lt;li&gt;Refunds increase block size variance. The theoretical maximum amount of actual gas consumed in a block is nearly twice the on-paper gas limit (as refunds add gas space for subsequent transactions in a block, though refunds are capped at 50% of a transaction&#x27;s gas used). This is not fatal, but is still undesirable, especially given that refunds can be used to maintain 2x usage spikes for far longer than EIP-1559 can.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;TBD&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MAX_REFUND_QUOTIENT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;For blocks where &lt;code&gt;block.number &amp;gt;= FORK_BLOCK&lt;&#x2F;code&gt;, the following changes apply.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; refund.&lt;&#x2F;li&gt;
&lt;li&gt;Replace &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; (as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt;) with &lt;code&gt;SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;code&gt; (4,800 gas as of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; + &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2930&#x2F;&quot;&gt;EIP-2930&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Reduce the max gas refunded after a transaction to &lt;code&gt;gas_used &#x2F;&#x2F; MAX_REFUND_QUOTIENT&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Remark: Previously &lt;em&gt;max gas refunded&lt;&#x2F;em&gt; was defined as &lt;code&gt;gas_used &#x2F;&#x2F; 2&lt;&#x2F;code&gt;. Here we
name the constant &lt;code&gt;2&lt;&#x2F;code&gt; as &lt;code&gt;MAX_REFUND_QUOTIENT&lt;&#x2F;code&gt; and change its value to &lt;code&gt;5&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;#specification&quot;&gt;EIP-2200&lt;&#x2F;a&gt;, three cases for refunds were introduced:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;If the original value is nonzero, and the new value is zero, add &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; (currently 15,000) gas to the refund counter&lt;&#x2F;li&gt;
&lt;li&gt;If the original value is zero, the current value is nonzero, and the new value is zero, add &lt;code&gt;SSTORE_SET_GAS - SLOAD_GAS&lt;&#x2F;code&gt; (currently 19,900) gas to the refund counter&lt;&#x2F;li&gt;
&lt;li&gt;If the original value is nonzero, the current value is a different nonzero value, and the new value equals the original value, add &lt;code&gt;SSTORE_RESET_GAS - SLOAD_GAS&lt;&#x2F;code&gt; (currently 4,900) gas to the refund counter&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Of these three, only (1) enables gastokens and allows a block to expend more gas on execution than the block gas limit. (2) does not have this property, because for the 19,900 refund to be obtained, &lt;em&gt;the same storage slot&lt;&#x2F;em&gt; must have been changed from zero to nonzero previously, costing 20,000 gas. The inability to obtain gas from clearing one storage slot and use it to edit another storage slot means that it cannot be used for gas tokens. Additionally, obtaining the refund requires &lt;em&gt;reverting&lt;&#x2F;em&gt; the effect of the storage write and expansion, so the refunded gas does not contribute to a client&#x27;s load in processing a block. (3) behaves similarly: the 4,900 refund can only be obtained when 5,000 gas had previously been spent on the same storage slot.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP deals with case (1). We can establish under what conditions a gastoken is nonviable (ie. you cannot get more gas out of a storage slot than you put in) by using a similar &quot;pairing&quot; argument, mapping each refund to a previous expenditure in the same transaction on the same storage slot. lf a storage slot is changed to zero when its original value is nonzero, there are two possibilities:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;This could be the first time that the storage slot is set to zero. In this case, we can pair this event with the &lt;code&gt;SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;code&gt; minimum cost of reading and editing the storage slot for the first time.&lt;&#x2F;li&gt;
&lt;li&gt;This could be the second or later time that the storage slot is set to zero. In this case, we can pair this event with the most recent previous time that the value was set &lt;em&gt;away&lt;&#x2F;em&gt; from zero, in which &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; gas is &lt;em&gt;removed&lt;&#x2F;em&gt; from the refund.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For the second and later event, it does not matter what value &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; has, because every refund of that size is paired with a refund &lt;em&gt;removal&lt;&#x2F;em&gt; of the same size. This leaves the first event. For the total gas expended on the slot to be guaranteed to be positive, we need &lt;code&gt;SSTORE_CLEARS_SCHEDULE &amp;lt;= SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;code&gt;. And so this EIP simply decreases &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; to the sum of those two costs.&lt;&#x2F;p&gt;
&lt;p&gt;One alternative intuition for this EIP is that there will not be a net refund for clearing data that has not yet been read (which is often &quot;useless&quot; data), but there will continue to be a net refund for clearing data that has been read (which is likely to be &quot;useful&quot; data).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Refunds are currently only applied &lt;em&gt;after&lt;&#x2F;em&gt; transaction execution, so they cannot affect how much gas is available to any particular call frame during execution. Hence, removing them will not break the ability of any code to execute, though it will render some applications economically nonviable.&lt;&#x2F;p&gt;
&lt;p&gt;Gas tokens will become valueless. DeFi arbitrage bots, which today frequently use either established gas token schemes or a custom alternative to reduce on-chain costs, would benefit from rewriting their code to remove calls to these no-longer-functional gas storage mechanisms.&lt;&#x2F;p&gt;
&lt;p&gt;However, fully preserving refunds in the &lt;code&gt;new = original = 0 != current&lt;&#x2F;code&gt; case, and keeping &lt;em&gt;some&lt;&#x2F;em&gt; refund in the other &lt;code&gt;nonzero -&amp;gt; zero&lt;&#x2F;code&gt; cases, ensures that a few key use cases that receive (and deserve) favorable gas cost treatment continue to do so. For example, &lt;code&gt;zero -&amp;gt; nonzero -&amp;gt; zero&lt;&#x2F;code&gt; storage set patterns continue to cost only ~100 gas. Two important examples of such patterns include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Anti-reentrancy locks (typically flipped from 0 to 1 right before a child call begins, and then flipped back to 0 when the child call ends)&lt;&#x2F;li&gt;
&lt;li&gt;ERC20 approve-and-send (the &quot;approved value&quot; goes from zero to nonzero when the token transfer is approved, and then back to zero when the token transfer processes)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;effect-on-storage-clearing-incentives&quot;&gt;Effect on storage clearing incentives&lt;&#x2F;h3&gt;
&lt;p&gt;A criticism of earlier refund removal EIPs (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3298&#x2F;&quot;&gt;EIP-3298&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3403&#x2F;&quot;&gt;EIP-3403&lt;&#x2F;a&gt;) is that these EIPs fully remove the incentive to set a value to zero, encouraging users to not fully clear a storage slot if they expect even the smallest probability that they will want to use that storage slot again.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if you have 1 unit of an ERC20 token and you are giving away or selling your entire balance, you could instead only give away 0.999999 units and leave the remainder behind. If you ever decide to re-acquire more of that token with the same account in the future, you would only have to pay 5000 gas (2100 for the read + 2900 for nonzero-to-nonzero set) for the &lt;code&gt;SSTORE&lt;&#x2F;code&gt; instead of 22100 (20000 for the zero-to-nonzero set). Today, this is counterbalanced by the 15000 refund for clearing, so you only have an incentive to do this if you are more than &lt;code&gt;15000 &#x2F; 17100 = 87.7%&lt;&#x2F;code&gt; sure that you will use the slot again; with EIP-3298 or EIP-3403 the counterbalancing incentive would not exist, so setting to nonzero is better if your chance of using the slot again is &lt;em&gt;any&lt;&#x2F;em&gt; value greater than 0%.&lt;&#x2F;p&gt;
&lt;p&gt;A refund of 4800 gas remains, so there is only be an incentive to keep a storage slot nonzero if you expect a probability of more than &lt;code&gt;4800 &#x2F; 17100 = 28.1%&lt;&#x2F;code&gt; that you will use that slot again. This is not perfect, but it is likely higher than the average person&#x27;s expectations of later re-acquiring a token with the same address if they clear their entire balance of it.&lt;&#x2F;p&gt;
&lt;p&gt;The capping of refunds to 1&#x2F;5 of gas expended means that this refund can only be used to increase the amount of storage write operations needed to process a block by at most 25%, limiting the ability to use this mechanic for storage-write-focused denial-of-service attacks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;eip-2929-gas-costs&quot;&gt;EIP-2929 Gas Costs&lt;&#x2F;h3&gt;
&lt;p&gt;Note, there is a difference between &#x27;hot&#x27; and &#x27;cold&#x27; slots. This table shows the values as of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; assuming that all touched storage slots were already &#x27;hot&#x27; (the difference being a one-time cost of &lt;code&gt;2100&lt;&#x2F;code&gt; gas).&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Used Gas&lt;&#x2F;th&gt;&lt;th&gt;Refund&lt;&#x2F;th&gt;&lt;th&gt;Original&lt;&#x2F;th&gt;&lt;th&gt;1st&lt;&#x2F;th&gt;&lt;th&gt;2nd&lt;&#x2F;th&gt;&lt;th&gt;3rd&lt;&#x2F;th&gt;&lt;th&gt;Effective gas (after refund)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;19900&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-11988&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;2800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-11988&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556003600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;2800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-11988&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600160005560006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;40118&lt;&#x2F;td&gt;&lt;td&gt;19900&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;20218&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600060005560016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5918&lt;&#x2F;td&gt;&lt;td&gt;17800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;-11882&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;with-reduced-refunds&quot;&gt;With reduced refunds&lt;&#x2F;h3&gt;
&lt;p&gt;If refunds were to be partially removed, by changing &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; from 15000 to 4800 (and removing selfdestruct refund) this would be the comparative table.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Used Gas&lt;&#x2F;th&gt;&lt;th&gt;Refund&lt;&#x2F;th&gt;&lt;th&gt;Original&lt;&#x2F;th&gt;&lt;th&gt;1st&lt;&#x2F;th&gt;&lt;th&gt;2nd&lt;&#x2F;th&gt;&lt;th&gt;3rd&lt;&#x2F;th&gt;&lt;th&gt;Effective gas (after refund)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;19900&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;20112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;4800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-1788&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;2800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;4800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-1788&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556003600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;2800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;4800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-1788&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;3012&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;212&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600160005560006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;40118&lt;&#x2F;td&gt;&lt;td&gt;19900&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;20218&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600060005560016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5918&lt;&#x2F;td&gt;&lt;td&gt;7600&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;-1682&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Refunds are not visible to transaction execution, so this should not have any impact on transaction execution logic.&lt;&#x2F;p&gt;
&lt;p&gt;The maximum amount of gas that can be spent on execution in a block is limited to the gas limit, if we do not count zero-to-nonzero &lt;code&gt;SSTORE&lt;&#x2F;code&gt;s that were later reset back to zero. It is okay to not count those, because if such an &lt;code&gt;SSTORE&lt;&#x2F;code&gt; is reset, storage is not expanded and the client does not need to actually adjust the Merke tree; the gas consumption is refunded, but the effort normally required by the client to process those opcodes is also cancelled. &lt;strong&gt;Clients should make sure to not do a storage write if &lt;code&gt;new_value = original_value&lt;&#x2F;code&gt;; this was a prudent optimization since the beginning of Ethereum but it becomes more important now.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Abstract Storage Bonds</title>
        <published>2021-04-05T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Yu Liu</name><uri>https://github.com/yuliu-debond</uri>
	</author>
	
	<author>
		<name>Varun Deshpande</name><uri>https://github.com/dr-chain</uri>
	</author>
	
	<author>
		<name>Cedric Ngakam</name><uri>https://github.com/drikssy</uri>
	</author>
	
	<author>
		<name>Dhruv Malik</name><uri>https://github.com/dhruvmalik007</uri>
	</author>
	
	<author>
		<name>Samuel Gwlanold Edoumou</name><uri>https://github.com/Edoumou</uri>
	</author>
	
	<author>
		<name>Toufic Batrice</name><uri>https://github.com/toufic0710</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3475/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3475-multiple-callable-bonds-standard/8691" />
        

        <id>https://wg-eips.ritovision.com/3475/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:3475"
            label="ERC-3475" />
        

        
        

        
        <summary type="html">Interface for creating tokenized obligations with abstract on-chain metadata storage</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3475/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This EIP allows the creation of tokenized obligations with abstract on-chain metadata storage. Issuing bonds with multiple redemption data cannot be achieved with existing token standards.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This EIP enables each bond class ID to represent a new configurable token type and corresponding to each class, corresponding bond nonces to represent an issuing condition or any other form of data in uint256. Every single nonce of a bond class can have its metadata, supply, and other redemption conditions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Bonds created by this EIP can also be batched for issuance&#x2F;redemption conditions for efficiency on gas costs and UX side. And finally, bonds created from this standard can be divided and exchanged in a secondary market.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Current LP (Liquidity Provider) tokens are simple &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; tokens with no complex data structure. To allow more complex reward and redemption logic to be stored on-chain, we need a new token standard that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Supports multiple token IDs&lt;&#x2F;li&gt;
&lt;li&gt;Can store on-chain metadata&lt;&#x2F;li&gt;
&lt;li&gt;Doesn&#x27;t require a fixed storage pattern&lt;&#x2F;li&gt;
&lt;li&gt;Is gas-efficient.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also Some benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This EIP allows the creation of any obligation with the same interface.&lt;&#x2F;li&gt;
&lt;li&gt;It will enable any 3rd party wallet applications or exchanges to read these tokens&#x27; balance and redemption conditions.&lt;&#x2F;li&gt;
&lt;li&gt;These bonds can also be batched as tradeable instruments. Those instruments can then be divided and exchanged in secondary markets.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bank: an entity that issues, redeems, or burns bonds after getting the necessary amount of liquidity. Generally, a single entity with admin access to the pool.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* transferFrom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; argument is the address of the bond holder whose balance is about to decrease.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; argument is the address of the bond recipient whose balance is about to increase.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the `Transaction[] calldata` (of type [&amp;#39;classId&amp;#39;, &amp;#39;nonceId&amp;#39;, &amp;#39;_amountBonds&amp;#39;]) structure defined in the rationale section below.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; transferFrom MUST have the `isApprovedFor(_from, _to, _transactions[i].classId)` approval to transfer `_from` address to `_to` address for given classId (i.e for Transaction tuple corresponding to all nonces).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;e.g:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* function transferFrom(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, 0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B, [IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* transfer from `_from` address, to `_to` address, `500000000` bonds of type class`1` and nonce `42`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* transferAllowanceFrom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; allows the transfer of only those bond types and nonces being allotted to the _to address using allowance().&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the holder whose balance is about to decrease.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the recipient whose balance is about to increase.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the `Transaction[] calldata` structure defined in the section `rationale` below.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; transferAllowanceFrom MUST have the `allowance(_from, msg.sender, _transactions[i].classId, _transactions[i].nonceId)` (where `i` looping for [ 0 ...Transaction.length - 1] ) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;e.g:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* function transferAllowanceFrom(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, 0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B, [IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* transfer from `_from` address, to `_to` address, `500000000` bonds of type class`1` and nonce `42`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAllowanceFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* issue &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; allows issuing any number of bond types (defined by values in Transaction tuple as param) to an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; it MUST be issued by a single entity (for instance, a role-based ownable contract that has integration with the liquidity pool of the deposited collateral by `_to` address).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_to` argument is the address to which the bond will be issued.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_transactions` is the `Transaction[] calldata` (ie array of issued bond class, bond nonce and amount of bonds to be issued).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; transferAllowanceFrom MUST have the `allowance(_from, msg.sender, _transactions[i].classId, _transactions[i].nonceId)` (where `i` looping for [ 0 ...Transaction.length - 1] ) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;e.g:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;example: issue(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,[IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;issues `1000` bonds with a class of `0` to address `0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef` with a nonce of `5`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; issue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transaction&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* redeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; permits redemption of bond from an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the calling of this function needs to be restricted to the bond issuer contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_from` is the address from which the bond will be redeemed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_transactions` is the `Transaction[] calldata` structure (i.e., array of tuples with the pairs of (class, nonce and amount) of the bonds that are to be redeemed). Further defined in the rationale section.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; redeem function for a given class, and nonce category MUST BE done after certain conditions for maturity (can be end time, total active liquidity, etc.) are met. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; furthermore, it SHOULD ONLY be called by the bank or secondary market maker contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;e.g:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* redeem(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, [IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;means “redeem from wallet address(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef), 500000000 of bond class1 and nonce 42.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; permits nullifying of the bonds (or transferring given bonds to address(0)).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; burn function for given class and nonce MUST BE called by only the controller contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address of the holder whose bonds are about to burn.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_transactions` is the `Transaction[] calldata` structure (i.e., array of tuple with the pairs of (class, nonce and amount) of the bonds that are to be burned). further defined in the rationale.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; burn function for a given class, and nonce category MUST BE done only after certain conditions for maturity (can be end time, total active liquidity, etc). &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; furthermore, it SHOULD ONLY be called by the bank or secondary market maker contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g:  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* burn(0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B,[IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* means burning 500000000 bonds of class 1 nonce 42 owned by address 0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allows `_spender` to withdraw from the msg.sender the bonds of `_amount` and type (classId and nonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If this function is called again, it overwrites the current allowance with the amount.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `approve()` should only be callable by the bank, or the owner of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_spender` argument is the address of the user who is approved to transfer the bonds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_transactions` is the `Transaction[] calldata` structure (ie array of tuple with the pairs of (class,nonce, and amount) of the bonds that are to be approved to be spend by _spender). Further defined in the rationale section.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* approve(0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B,[IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* means owner of address 0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B is approved to manage 500 bonds from class 1 and Nonce 14.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* SetApprovalFor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; enable or disable approval for a third party (“operator”) to manage all the Bonds in the given class of the caller’s bonds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If this function is called again, it overwrites the current allowance with the amount.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `approve()` should only be callable by the bank or the owner of the account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_operator` is the address to add to the set of authorized operators.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `classId` is the class id of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `_approved` is true if the operator is approved (based on the conditions provided), false meaning approval is revoked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; contract MUST define internal function regarding the conditions for setting approval and should be callable only by bank or owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g: setApprovalFor(0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B,0,true);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* means that address 0x82a55a613429Aeb3D01fbE6841bE1AcA4fFD5b2B is authorized to transfer bonds from class 0 (across all nonces).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* totalSupply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Here, total supply includes burned and redeemed supply.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding class Id of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce Id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; supply of the bonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* totalSupply(0, 1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* it finds the total supply of the bonds of classid 0 and bond nonce 1.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* redeemedSupply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the redeemed supply of the bond identified by (classId,nonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding class id of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; supply of bonds redeemed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; redeemedSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* activeSupply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the active supply of the bond defined by (classId,NonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; non-redeemed, active supply. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; activeSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* burnedSupply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the burned supply of the bond in defined by (classId,NonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; gets&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the supply of bonds for given classId and nonceId that are already burned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burnedSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* balanceOf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the balance of the bonds (nonReferenced) of given classId and bond nonce held by the address `_account`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the owner whose balance is to be determined.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; this also consists of bonds that are redeemed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* classMetadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the JSON metadata of the classes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata SHOULD follow a set of structures explained later in the metadata.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the index-id given bond class information.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; JSON metadata of the nonces. — e.g. `[title, type, description]`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; classMetadata&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* nonceMetadata &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the JSON metadata of the nonces.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The metadata SHOULD follow a set of structures explained later in metadata.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonce id of the given bond class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the index of the JSON storage for given metadata information. more is defined in metadata.md.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns the JSON metadata of the nonces. — e.g. `[title, type, description]`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nonceMetadata&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* classValues&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; allows anyone to read the values (stored in struct Values for different class) for given bond class `classId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the values SHOULD follow a set of structures as explained in metadata along with correct mapping corresponding to the given metadata structure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the index of the JSON storage for given metadata information of all values of given metadata. more is defined in metadata.md.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns the Values of the class metadata. — e.g. `[string, uint, address]`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; classValues&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Values&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* nonceValues&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; allows anyone to read the values (stored in struct Values for different class) for given bond (`nonceId`,`classId`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the values SHOULD follow a set of structures explained in metadata along with correct mapping corresponding to the given metadata structure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the index of the JSON storage for given metadata information of all values of given metadata. More is defined in metadata.md.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns the Values of the class metadata. — e.g. `[string, uint, address]`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nonceValues&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; metadataId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Values&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* getProgress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the parameters to determine the current status of bonds maturity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the conditions of redemption SHOULD be defined with one or several internal functions. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonceId of the given bond class . &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns progressAchieved defines the metric (either related to % liquidity, time, etc.) that defines the current status of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns progressRemaining defines the metric that defines the remaining time&#x2F; remaining progress. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getProgress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; progressAchieved&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; progressRemaining&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* allowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizes to set the allowance for given `_spender` by `_owner` for all bonds identified by (classId, nonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the owner of bond(and also msg.sender).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the address authorized to spend the bonds held by _owner of info (classId, nonceId).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the corresponding classId of the bond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is the nonceId of the given bond class. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the _amount which spender is still allowed to withdraw from _owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* isApprovedFor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; returns true if address _operator is approved for managing the account’s bonds class.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Queries the approval status of an operator for a given owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _owner is the owner of bonds. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _operator is the EOA &#x2F;contract, whose status for approval on bond class for this approval is checked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* @returns “true” if the operator is approved, “false” if not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&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;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* Issue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Issue MUST trigger when Bonds are issued. This SHOULD not include zero value Issuing.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This SHOULD not include zero value issuing.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Issue MUST be triggered when the operator (i.e Bank address) contract issues bonds to the given entity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* eg: emit Issue(_operator, 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,[IERC3475.Transaction(1,14,500)]); &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* issue by address(operator) 500 Bonds(nonce14,class 1) to address 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Issue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* Redeem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Redeem MUST trigger when Bonds are redeemed. This SHOULD not include zero value redemption.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*e.g: emit Redeem(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,0x492Af743654549b12b1B807a9E0e8F397E44236E,[IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* emit event when 5000 bonds of class 1, nonce 14 owned by address 0x492Af743654549b12b1B807a9E0e8F397E44236E are being redeemed by 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* Burn.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `Burn` MUST trigger when the bonds are being redeemed via staking (or being invalidated) by the bank contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `Burn` MUST trigger when Bonds are burned. This SHOULD not include zero value burning.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g : emit Burn(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,0x492Af743654549b12b1B807a9E0e8F397E44236E,[IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* emits event when 500 bonds of owner 0x492Af743654549b12b1B807a9E0e8F397E44236E of type (class 1, nonce 14) are burned by operator  0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* Transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; its emitted when the bond is transferred by address(operator) from owner address(_from) to address(_to) with the bonds transferred, whose params are defined by _transactions struct array. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer MUST trigger when Bonds are transferred. This SHOULD not include zero value transfers.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer event with the _from `0x0` MUST not create this event(use `event Issued` instead). &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* e.g  emit Transfer(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, 0x492Af743654549b12b1B807a9E0e8F397E44236E, _to, [IERC3475.Transaction(1,14,500)]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* transfer by address(_operator) amount 500 bonds with (Class 1 and Nonce 14) from 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, to address(_to).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _transactions&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* ApprovalFor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; its emitted when address(_owner) approves the address(_operator) to transfer his bonds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approval MUST trigger when bond holders are approving an _operator. This SHOULD not include zero value approval. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* eg: emit ApprovalFor(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, 0x492Af743654549b12b1B807a9E0e8F397E44236E, true);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;* this means 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef gives 0x492Af743654549b12b1B807a9E0e8F397E44236E access permission for transfer of its bonds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&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;Metadata&lt;&#x2F;strong&gt;:
The metadata of a bond class or nonce is stored as an array of JSON objects, represented by the following types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: all of the metadata schemas are referenced from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;assets&#x2F;Metadata&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-description&quot;&gt;1. Description:&lt;&#x2F;h3&gt;
&lt;p&gt;This defines the additional information about the nature of data being stored in the nonce&#x2F;class metadata structures. They are defined using the structured explained &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;assets&#x2F;Metadata&#x2F;#1-description-metadata&quot;&gt;here&lt;&#x2F;a&gt;. this will then be used by the frontend of the respective entities participating in the bond markets to interpret the data which is compliant with their jurisdiction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-nonce&quot;&gt;2. Nonce:&lt;&#x2F;h3&gt;
&lt;p&gt;The key value for indexing the information is the &#x27;class&#x27; field. Following are the rules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The title can be any alphanumeric type that is differentiated by the description of metadata (although it can be dependent on certain jurisdictions).&lt;&#x2F;li&gt;
&lt;li&gt;The title SHOULD not be EMPTY.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some specific examples of metadata can be the localization of bonds, jurisdiction details etc., and they can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;assets&#x2F;Metadata&#x2F;&quot;&gt;metadata.md&lt;&#x2F;a&gt; example description.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-class-metadata&quot;&gt;3. Class metadata:&lt;&#x2F;h3&gt;
&lt;p&gt;This structure defines the details of the class information (symbol, risk information, etc.). the example is explained &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;assets&#x2F;Metadata&#x2F;&quot;&gt;here&lt;&#x2F;a&gt; in the class metadata section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-decoding-data&quot;&gt;4. Decoding data&lt;&#x2F;h3&gt;
&lt;p&gt;First, the functions for analyzing the metadata (i.e &lt;code&gt;ClassMetadata&lt;&#x2F;code&gt; and &lt;code&gt;NonceMetadata&lt;&#x2F;code&gt;) are to be used by the corresponding frontend to decode the information of the bond.&lt;&#x2F;p&gt;
&lt;p&gt;This is done via overriding the function interface for functions &lt;code&gt;classValues&lt;&#x2F;code&gt; and &lt;code&gt;nonceValues&lt;&#x2F;code&gt; by defining the key (which SHOULD be an index) to read the corresponding information stored as a JSON object.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;symbol&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;defines the unique identifier name in following format: (symbol, bondType, maturity in months)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;values&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Class Name 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Class Name 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DBIT Fix 6M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;e.g. In the above example, to get the &lt;code&gt;symbol&lt;&#x2F;code&gt; of the given class id, we can use the class id as a key to get the &lt;code&gt;symbol&lt;&#x2F;code&gt; value in the values, which then can be used for fetching the detail for instance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;metadata-structure&quot;&gt;Metadata structure&lt;&#x2F;h3&gt;
&lt;p&gt;Instead of storing the details about the class and their issuances to the user (ie nonce) externally, we store the details in the respective structures. Classes represent the different bond types, and nonces represent the various period of issuances. Nonces under the same class share the same metadata. Meanwhile, nonces are non-fungible. Each nonce can store a different set of metadata. Thus, upon transfer of a bond, all the metadata will be transferred to the new owner of the bond.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; stringValue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt; uintValue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; addressValue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt; boolValue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; bytesValue&lt;&#x2F;span&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; title&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; _type&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; description&lt;&#x2F;span&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;h3 id=&quot;batch-function&quot;&gt;Batch function&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP supports batch operations. It allows the user to transfer different bonds along with their metadata to a new address instantaneously in a single transaction. After execution, the new owner holds the right to reclaim the face value of each of the bonds. This mechanism helps with the &quot;packaging&quot; of bonds–helpful in use cases like trades on a secondary market.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; classId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; nonceId&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&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&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where:
The &lt;code&gt;classId&lt;&#x2F;code&gt; is the class id of the bond.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;nonceId&lt;&#x2F;code&gt; is the nonce id of the given bond class. This param is for distinctions of the issuing conditions of the bond.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;_amount&lt;&#x2F;code&gt; is the amount of the bond for which the spender is approved.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;amm-optimization&quot;&gt;AMM optimization&lt;&#x2F;h3&gt;
&lt;p&gt;One of the most obvious use cases of this EIP is the multilayered pool. The early version of AMM uses a separate smart contract and an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; LP token to manage a pair. By doing so, the overall liquidity inside of one pool is significantly reduced and thus generates unnecessary gas spent and slippage. Using this EIP standard, one can build a big liquidity pool with all the pairs inside (thanks to the presence of the data structures consisting of the liquidity corresponding to the given class and nonce of bonds). Thus by knowing the class and nonce of the bonds, the liquidity can be represented as the percentage of a given token pair for the owner of the bond in the given pool. Effectively, the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; LP token (defined by a unique smart contract in the pool factory contract) is aggregated into a single bond and consolidated into a single pool.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The reason behind the standard&#x27;s name (abstract storage bond) is its ability to store all the specifications (metadata&#x2F;values and transaction as defined in the following sections) without needing external storage on-chain&#x2F;off-chain.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Any contract that inherits the interface of this EIP is compatible. This compatibility exists for issuer and receiver of the bonds. Also any client EOA wallet can be compatible with the standard if they are able to sign &lt;code&gt;issue()&lt;&#x2F;code&gt; and &lt;code&gt;redeem()&lt;&#x2F;code&gt; commands.&lt;&#x2F;p&gt;
&lt;p&gt;However, any existing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; token contract can issue its bonds by delegating the minting role to a bank contract with the interface of this standard built-in. Check out our reference implementation for the correct interface definition.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure the indexing of transactions throughout the bond lifecycle (i.e &quot;Issue&quot;, &quot;Redeem&quot; and &quot;Transfer&quot; functions), events cited in specification section MUST be emitted when such transaction is passed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note that the this standard interface is also compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;interface.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However, creating a separate bank contract is recommended for reading the bonds and future upgrade needs.&lt;&#x2F;p&gt;
&lt;p&gt;Acceptable collateral can be in the form of fungible (like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt;), non-fungible (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;EIP-1155&lt;&#x2F;a&gt;) , or other bonds represented by this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test-case for the minimal reference implementation is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;.&#x2F;assets&#x2F;ERC3475.test.ts&quot;&gt;here&lt;&#x2F;a&gt;. Use the Truffle box to compile and test the contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;.&#x2F;assets&#x2F;interfaces&#x2F;IERC3475.sol&quot;&gt;Interface&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3475&#x2F;.&#x2F;assets&#x2F;ERC3475.sol&quot;&gt;Basic Example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This demonstration shows only minimalist implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;function setApprovalFor(address _operatorAddress)&lt;&#x2F;code&gt; gives the operator role to &lt;code&gt;_operatorAddress&lt;&#x2F;code&gt;. It has all the permissions to transfer, burn and redeem bonds by default.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the owner wants to give a one-time allocation to an address for specific bonds(classId,bondsId), he should call the &lt;code&gt;function approve()&lt;&#x2F;code&gt; giving the &lt;code&gt;Transaction[]&lt;&#x2F;code&gt; allocated rather than approving all the classes using &lt;code&gt;setApprovalFor&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>MetaProxy Standard</title>
        <published>2021-03-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>pinkiebell</name><uri>https://github.com/pinkiebell</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3448/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-3448-metaproxy-factory/5834" />
        

        <id>https://wg-eips.ritovision.com/3448/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:3448"
            label="ERC-3448" />
        

        
        

        
        <summary type="html">A minimal bytecode implementation for creating proxy contracts with immutable metadata attached to the bytecode</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3448/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;By standardizing on a known minimal bytecode proxy implementation with support for immutable metadata, this standard allows users and third party tools (e.g. Etherscan) to:
(a) simply discover that a contract will always redirect in a known manner and
(b) depend on the behavior of the code at the destination contract as the behavior of the redirecting contract and
(c) verify&#x2F;view the attached metadata.&lt;&#x2F;p&gt;
&lt;p&gt;Tooling can interrogate the bytecode at a redirecting address to determine the location of the code that will run along with the associated metadata - and can depend on representations about that code (verified source, third-party audits, etc).
This implementation forwards all calls via &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; and any (calldata) input plus the metadata at the end of the bytecode to the implementation contract and then relays the return value back to the caller.
In the case where the implementation reverts, the revert is passed back along with the payload data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This standard supports use-cases wherein it is desirable to clone exact contract functionality with different parameters at another address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The exact bytecode of the MetaProxy contract is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                              20 bytes target contract address&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;363d3d373d3d3d3d60368038038091363936013d7300000000000000000000000000000000000000005af43d3d93803e603457fd5bf3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;wherein the bytes at indices 21 - 41 (inclusive) are replaced with the 20 byte address of the master functionality contract.
Additionally, everything after the MetaProxy bytecode can be arbitrary metadata and the last 32 bytes (one word) of the bytecode must indicate the length of the metadata in bytes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;54 bytes metaproxy&amp;gt; &amp;lt;arbitrary data&amp;gt; &amp;lt;length in bytes of arbitrary data (uint256)&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The goals of this effort have been the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a cheap way of storing immutable metadata for each child instead of using storage slots&lt;&#x2F;li&gt;
&lt;li&gt;inexpensive deployment of clones&lt;&#x2F;li&gt;
&lt;li&gt;handles error return bubbling for revert messages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no backwards compatibility issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Tested with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;invocation with no arguments&lt;&#x2F;li&gt;
&lt;li&gt;invocation with arguments&lt;&#x2F;li&gt;
&lt;li&gt;invocation with return values&lt;&#x2F;li&gt;
&lt;li&gt;invocation with revert (confirming reverted payload is transferred)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A solidity contract with the above test cases can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3448&#x2F;.&#x2F;assets&#x2F;MetaProxyTest.sol&quot;&gt;in the EIP asset directory&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3448&#x2F;.&#x2F;assets&#x2F;MetaProxyFactory.sol&quot;&gt;in the EIP asset directory&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deployment-bytecode&quot;&gt;Deployment bytecode&lt;&#x2F;h3&gt;
&lt;p&gt;A annotated version of the deploy bytecode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; PUSH1 11;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CODESIZE;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; SUB;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; DUP1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; PUSH1 11;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CODECOPY;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;metaproxy&quot;&gt;MetaProxy&lt;&#x2F;h3&gt;
&lt;p&gt;A annotated version of the MetaProxy bytecode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; copy args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CALLDATASIZE;   calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, 0, calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CALLDATACOPY;&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; RETURNDATASIZE; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, 0, 0, 0&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; PUSH1 54;       54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; DUP1;           54, 54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CODESIZE;       codesize, 54, 54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; SUB;            codesize-54, 54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; DUP1;           codesize-54, codesize-54, 54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; SWAP2;          54, codesize-54, codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CALLDATASIZE;   calldatasize, 54, codesize-54, codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; CODECOPY;       codesize-54, 0, 0, 0, 0&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; CALLDATASIZE;   calldatasize, codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; ADD;            calldatasize+codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; 0, calldatasize+codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; PUSH20 0;       addr, 0, calldatasize+codesize-54, 0, 0, 0, 0 - zero is replaced with shl(96, address())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; GAS;            gas, addr, 0, calldatasize+codesize-54, 0, 0, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; DELEGATECALL;   (gas, addr, 0, calldatasize() + metadata, 0, 0) delegatecall to the target contract;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; returndatasize, retcode, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATASIZE; returndatasize, returndatasize, retcode, 0, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; SWAP4;          0, returndatasize, retcode, 0, returndatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; DUP1;           0, 0, returndatasize, retcode, 0, returndatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURNDATACOPY; (0, 0, returndatasize) - Copy everything into memory that the call returned&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; stack = retcode, 0, returndatasize # this is for either revert(0, returndatasize()) or return (0, returndatasize())&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; PUSH1 _SUCCESS_; push jumpdest of _SUCCESS_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; JUMPI;          jump if delegatecall returned `1`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; REVERT;         (0, returndatasize()) if delegatecall returned `0`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; JUMPDEST _SUCCESS_;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; RETURN;         (0, returndatasize()) if delegatecall returned non-zero (1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h3&gt;
&lt;p&gt;The following code snippets serve only as suggestions and are not a discrete part of this standard.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;proxy-construction-with-bytes-from-abi-encode&quot;&gt;Proxy construction with bytes from abi.encode&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MetaProxy construction via abi encoded bytes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createFromBytes&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; c&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proxy&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; creates a new proxy where the metadata is the result of abi.encode()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  proxy &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; MetaProxyFactory&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_metaProxyFromBytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;  require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proxy &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; optional one-time setup, a constructor() substitute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  MyContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proxy&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;init&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;proxy-construction-with-bytes-from-calldata&quot;&gt;Proxy construction with bytes from calldata&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MetaProxy construction via calldata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createFromCalldata&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; c&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; proxy&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; creates a new proxy where the metadata is everything after the 4th byte from calldata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  proxy &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; MetaProxyFactory&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_metaProxyFromCalldata&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;  require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proxy &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; optional one-time setup, a constructor() substitute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  MyContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;proxy&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;init&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;retrieving-the-metadata-from-calldata-and-abi-decode&quot;&gt;Retrieving the metadata from calldata and abi.decode&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the metadata of this (MetaProxy) contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only relevant with contracts created via the MetaProxy standard.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function is aimed to be invoked with- &amp;amp; without a call.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getMetadataWithoutCall&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 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 class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; c&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&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; posOfMetadataSize &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;posOfMetadataSize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; dataPtr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;posOfMetadataSize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; increment free memory pointer by metadata size + 32 bytes (length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; memPtr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-entity z-name&quot;&gt;    calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;memPtr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; dataPtr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;retrieving-the-metadata-via-a-call-to-self&quot;&gt;Retrieving the metadata via a call to self&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the metadata of this (MetaProxy) contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only relevant with contracts created via the MetaProxy standard.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function is aimed to be invoked via a call.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getMetadataViaCall&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 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 class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;  uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; c&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&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; posOfMetadataSize &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;posOfMetadataSize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; dataPtr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;posOfMetadataSize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; dataPtr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&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;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;Apart from the examples above, it is also possible to use Solidity Structures or any custom data encoding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This standard only covers the bytecode implementation and does not include any serious side effects of itself.
The reference implementation only serves as a example. It is highly recommended to research side effects depending on how the functionality is used and implemented in any project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Reject new contract code starting with the 0xEF byte</title>
        <published>2021-03-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Paweł Bylica</name><uri>https://github.com/chfast</uri>
	</author>
	
	<author>
		<name>Andrei Maiboroda</name><uri>https://github.com/gumb0</uri>
	</author>
	
	<author>
		<name>Alexey Akhunov</name><uri>https://github.com/AlexeyAkhunov</uri>
	</author>
	
	<author>
		<name>Christian Reitwiessner</name><uri>https://github.com/chriseth</uri>
	</author>
	
	<author>
		<name>Martin Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3541/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/evm-object-format-eof/5727" />
        

        <id>https://wg-eips.ritovision.com/3541/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:3541"
            label="EIP-3541" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3541/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Disallow new code starting with the &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte to be deployed. Code already existing in the account trie starting with &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte is not affected semantically by this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Contracts conforming to the EVM Object Format (EOF) are going to be validated at deploy time. In order to guarantee that every EOF-formatted contract in the state is valid, we need to prevent already deployed (and not validated) contracts from being recognized as such format. This will be achieved by choosing a byte sequence for the &lt;em&gt;magic&lt;&#x2F;em&gt; that doesn&#x27;t exist in any of the already deployed contracts. To prevent the growth of the search space and to limit the analysis to the contracts existing before this fork, we disallow the starting byte of the format (the first byte of the magic).&lt;&#x2F;p&gt;
&lt;p&gt;Should the EVM Object Format proposal not be deployed in the future, the &lt;em&gt;magic&lt;&#x2F;em&gt; can be used by other features depending on versioning. In the case versioning becomes obsolete, it is simple to roll this back by allowing contracts starting with the &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte to be deployed again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;After &lt;code&gt;block.number == HF_BLOCK&lt;&#x2F;code&gt; new contract creation (via create transaction, &lt;code&gt;CREATE&lt;&#x2F;code&gt; or &lt;code&gt;CREATE2&lt;&#x2F;code&gt; instructions) results in an exceptional abort if the &lt;em&gt;code&lt;&#x2F;em&gt;&#x27;s first byte is &lt;code&gt;0xEF&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;remarks&quot;&gt;Remarks&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;em&gt;initcode&lt;&#x2F;em&gt; is the code executed in the context of the &lt;em&gt;create&lt;&#x2F;em&gt; transaction, &lt;code&gt;CREATE&lt;&#x2F;code&gt;, or &lt;code&gt;CREATE2&lt;&#x2F;code&gt; instructions. The &lt;em&gt;initcode&lt;&#x2F;em&gt; returns &lt;em&gt;code&lt;&#x2F;em&gt; (via the &lt;code&gt;RETURN&lt;&#x2F;code&gt; instruction), which is inserted into the account. See section 7 (&quot;Contract Creation&quot;) in the Yellow Paper for more information.&lt;&#x2F;p&gt;
&lt;p&gt;The opcode &lt;code&gt;0xEF&lt;&#x2F;code&gt; is currently an undefined instruction, therefore: &lt;em&gt;It pops no stack items and pushes no stack items, and it causes an exceptional abort when executed.&lt;&#x2F;em&gt; This means &lt;em&gt;initcode&lt;&#x2F;em&gt; or already deployed &lt;em&gt;code&lt;&#x2F;em&gt; starting with this instruction will continue to abort execution.&lt;&#x2F;p&gt;
&lt;p&gt;The exceptional abort due to &lt;em&gt;code&lt;&#x2F;em&gt; starting with &lt;code&gt;0xEF&lt;&#x2F;code&gt; behaves exactly the same as any other exceptional abort that can occur during &lt;em&gt;initcode&lt;&#x2F;em&gt; execution, i.e. in case of abort all gas provided to a &lt;code&gt;CREATE*&lt;&#x2F;code&gt; or create transaction is consumed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte was chosen because it resembles &lt;strong&gt;E&lt;&#x2F;strong&gt;xecutable &lt;strong&gt;F&lt;&#x2F;strong&gt;ormat.&lt;&#x2F;p&gt;
&lt;p&gt;Contracts using unassigned opcodes are generally understood to be at risk of changing semantics. Hence using the unassigned &lt;code&gt;0xEF&lt;&#x2F;code&gt; should have lesser effects, than choosing an assigned opcode, such as &lt;code&gt;0xFD&lt;&#x2F;code&gt; (&lt;code&gt;REVERT&lt;&#x2F;code&gt;), &lt;code&gt;0xFE&lt;&#x2F;code&gt; (&lt;code&gt;INVALID)&lt;&#x2F;code&gt;, or &lt;code&gt;0xFF&lt;&#x2F;code&gt; (&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;). Arguably while such contracts may not be very useful, they are still using valid opcodes.&lt;&#x2F;p&gt;
&lt;p&gt;Analysis in May 2021, on &lt;code&gt;18084433&lt;&#x2F;code&gt; contracts in state, showed that there are 0 existing contracts starting with the &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte, as opposed to 1, 4, and 12 starting with &lt;code&gt;0xFD&lt;&#x2F;code&gt;, &lt;code&gt;0xFE&lt;&#x2F;code&gt;, and &lt;code&gt;0xFF&lt;&#x2F;code&gt;, respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Each test case below may be executed in 3 different contexts:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;create transaction (no account code)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CREATE&lt;&#x2F;code&gt;, with account code: &lt;code&gt;0x6000356000523660006000f0151560165760006000fd5b&lt;&#x2F;code&gt; (Yul code: &lt;code&gt;mstore(0, calldataload(0)) if iszero(create(0, 0, calldatasize())) { revert(0, 0) }&lt;&#x2F;code&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CREATE2&lt;&#x2F;code&gt;, with account code: &lt;code&gt;0x60003560005260003660006000f5151560185760006000fd5b&lt;&#x2F;code&gt; (Yul code: &lt;code&gt;mstore(0, calldataload(0)) if iszero(create2(0, 0, calldatasize(), 0)) { revert(0, 0) }&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Case&lt;&#x2F;th&gt;&lt;th&gt;Calldata&lt;&#x2F;th&gt;&lt;th&gt;Expected result&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;deploy one byte &lt;code&gt;ef&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x60ef60005360016000f3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;new contract not deployed, transaction fails&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;deploy two bytes &lt;code&gt;ef00&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x60ef60005360026000f3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;new contract not deployed, transaction fails&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;deploy three bytes &lt;code&gt;ef0000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x60ef60005360036000f3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;new contract not deployed, transaction fails&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;deploy 32 bytes &lt;code&gt;ef00...00&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x60ef60005360206000f3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;new contract not deployed, transaction fails&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;deploy one byte &lt;code&gt;fe&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x60fe60005360016000f3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;new contract deployed, transaction succeeds&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is a breaking change given new code starting with the &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte will not be deployable, and contract creation will result in a failure. However, given bytecode is executed starting at its first byte, code deployed with &lt;code&gt;0xEF&lt;&#x2F;code&gt; as the first byte is not executable anyway.&lt;&#x2F;p&gt;
&lt;p&gt;While this means no currently executable contract is affected, it does rejects deployment of new data contracts starting with the &lt;code&gt;0xEF&lt;&#x2F;code&gt; byte.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The authors are not aware of any security or DoS risks posed by this change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>PUSH0 instruction</title>
        <published>2021-02-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Hugo De la cruz</name><uri>https://github.com/hugo-dc</uri>
	</author>
	
	<author>
		<name>Paweł Bylica</name><uri>https://github.com/chfast</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3855/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3855-push0-instruction/7014" />
        

        <id>https://wg-eips.ritovision.com/3855/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:3855"
            label="EIP-3855" />
        

        
        

        
        <summary type="html">Introduce a new instruction which pushes the constant value 0 onto the stack</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3855/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce the &lt;code&gt;PUSH0&lt;&#x2F;code&gt; (&lt;code&gt;0x5f&lt;&#x2F;code&gt;) instruction, which pushes the constant value 0 onto the stack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many instructions expect offsets as inputs, which in a number of cases are zero. A good example is the return data parameters of &lt;code&gt;CALLs&lt;&#x2F;code&gt;, which are set to zeroes in case the contract prefers using &lt;code&gt;RETURNDATA*&lt;&#x2F;code&gt;. This is only one example, but there are many other reasons why a contract would need to push a zero value. They can achieve that today by &lt;code&gt;PUSH1 0&lt;&#x2F;code&gt;, which costs 3 gas at runtime, and is encoded as two bytes which means &lt;code&gt;2 * 200&lt;&#x2F;code&gt; gas deployment cost.&lt;&#x2F;p&gt;
&lt;p&gt;Because of the overall cost many try to use various other instructions to achieve the same effect. Common examples include &lt;code&gt;PC&lt;&#x2F;code&gt;, &lt;code&gt;MSIZE&lt;&#x2F;code&gt;, &lt;code&gt;CALLDATASIZE&lt;&#x2F;code&gt;, &lt;code&gt;RETURNDATASIZE&lt;&#x2F;code&gt;, &lt;code&gt;CODESIZE&lt;&#x2F;code&gt;, &lt;code&gt;CALLVALUE&lt;&#x2F;code&gt;, and &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt;. Some of these cost only 2 gas and are a single byte long, but their value can depend on the context.&lt;&#x2F;p&gt;
&lt;p&gt;We have conducted an analysis on Mainnet (block ranges 8,567,259…8,582,058 and 12,205,970…12,817,405), and ~11.5% of all the &lt;code&gt;PUSH*&lt;&#x2F;code&gt; instructions executed push a value of zero.&lt;&#x2F;p&gt;
&lt;p&gt;The main motivations for this change include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reducing contract code size.&lt;&#x2F;li&gt;
&lt;li&gt;Reducing the risk of contracts (mis)using various instructions as an optimisation measure. Repricing&#x2F;changing those instructions can be more risky.&lt;&#x2F;li&gt;
&lt;li&gt;Reduce the need to use &lt;code&gt;DUP&lt;&#x2F;code&gt; instructions for duplicating zeroes.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To put the &quot;waste&quot; into perspective, across existing accounts 340,557,331 bytes are wasted on &lt;code&gt;PUSH1 00&lt;&#x2F;code&gt; instructions, which means 68,111,466,200 gas was spent to deploy them. In practice a lot of these accounts share identical bytecode with others, so their total stored size in clients is lower, however the deploy time cost must have been paid nevertheless.&lt;&#x2F;p&gt;
&lt;p&gt;An example for 2) is changing the behaviour of &lt;code&gt;RETURNDATASIZE&lt;&#x2F;code&gt; such that it may not be guaranteed to be zero at the beginning of the call frame.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The instruction &lt;code&gt;PUSH0&lt;&#x2F;code&gt; is introduced at &lt;code&gt;0x5f&lt;&#x2F;code&gt;. It has no immediate data, pops no items from the stack, and places a single item with the value 0 onto the stack. The cost of this instruction is 2 gas (aka &lt;code&gt;base&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gas-cost&quot;&gt;Gas cost&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;base&lt;&#x2F;code&gt; gas cost is used for instructions which place constant values onto the stack, such as &lt;code&gt;ADDRESS&lt;&#x2F;code&gt;, &lt;code&gt;ORIGIN&lt;&#x2F;code&gt;, and so forth.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;opcode&quot;&gt;Opcode&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;0x5f&lt;&#x2F;code&gt; means it is in a &quot;contiguous&quot; space with the rest of the &lt;code&gt;PUSH&lt;&#x2F;code&gt; implementations and potentially could share the implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a new opcode which did not exist previously. Already deployed contracts using this opcode could change their behaviour after this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;5F&lt;&#x2F;code&gt; -- successful execution, stack consist of a single item, set to zero&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;5F5F..5F&lt;&#x2F;code&gt; (1024 times) -- successful execution, stack consists of 1024 items, all set to zero&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;5F5F..5F&lt;&#x2F;code&gt; (1025 times) -- execution aborts due to out of stack&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The authors are not aware of any impact on security. Note that jumpdest-analysis is unaffected, as &lt;code&gt;PUSH0&lt;&#x2F;code&gt; has no immediate data bytes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>MCOPY - Memory copying instruction</title>
        <published>2021-02-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Paul Dworzanski</name><uri>https://github.com/poemm</uri>
	</author>
	
	<author>
		<name>Jared Wasinger</name><uri>https://github.com/jwasinger</uri>
	</author>
	
	<author>
		<name>Casey Detrio</name><uri>https://github.com/cdetrio</uri>
	</author>
	
	<author>
		<name>Pawel Bylica</name><uri>https://github.com/chfast</uri>
	</author>
	
	<author>
		<name>Charles Cooper</name><uri>https://github.com/charles-cooper</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5656/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-5656-mcopy-instruction/10890" />
        

        <id>https://wg-eips.ritovision.com/5656/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:5656"
            label="EIP-5656" />
        

        
        

        
        <summary type="html">An efficient EVM instruction for copying memory areas</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5656/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Provide an efficient EVM instruction for copying memory areas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Memory copying is a basic operation, yet implementing it on the EVM comes with overhead.&lt;&#x2F;p&gt;
&lt;p&gt;This was recognised and alleviated early on with the introduction of the &quot;identity&quot; precompile, which accomplishes
memory copying by the use of &lt;code&gt;CALL&lt;&#x2F;code&gt;&#x27;s input and output memory offsets. Its cost is &lt;code&gt;15 + 3 * (length &#x2F; 32)&lt;&#x2F;code&gt; gas, plus
the call overhead. The identity precompile was rendered ineffective by the raise of the cost of &lt;code&gt;CALL&lt;&#x2F;code&gt; to 700, but subsequently
the reduction by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; made it slightly more economical.&lt;&#x2F;p&gt;
&lt;p&gt;Copying exact words can be accomplished with &lt;code&gt;&amp;lt;offset&amp;gt; MLOAD &amp;lt;offset&amp;gt; MSTORE&lt;&#x2F;code&gt; or &lt;code&gt;&amp;lt;offset&amp;gt; DUP1 MLOAD DUP2 MSTORE&lt;&#x2F;code&gt;,
at a cost of at least 12 gas per word. This is fairly efficient if the offsets are known upfront and the copying can be unrolled.
In case copying is implemented at runtime with arbitrary starting offsets, besides the control flow overhead, the offset
will need to be incremented using &lt;code&gt;32 ADD&lt;&#x2F;code&gt;, adding at least 6 gas per word.&lt;&#x2F;p&gt;
&lt;p&gt;Copying non-exact words is more tricky, as for the last partial word, both the source and destination needs to be loaded,
masked, or&#x27;d, and stored again. This overhead is significant. One edge case is if the last &quot;partial word&quot; is a single byte,
it can be efficiently stored using &lt;code&gt;MSTORE8&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As example use case, copying 256 bytes costs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;at least 757 gas pre-EIP-2929 using the identity precompile&lt;&#x2F;li&gt;
&lt;li&gt;at least 157 gas post-EIP-2929 using the identity precompile&lt;&#x2F;li&gt;
&lt;li&gt;at least 96 gas using unrolled &lt;code&gt;MLOAD&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;MSTORE&lt;&#x2F;code&gt; instructions&lt;&#x2F;li&gt;
&lt;li&gt;27 gas using this EIP&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;According to an analysis of blocks 10537502 to 10538702, roughly 10.5% of memory copies would have had improved performance with the
availability of an &lt;code&gt;MCOPY&lt;&#x2F;code&gt; instruction.&lt;&#x2F;p&gt;
&lt;p&gt;Memory copying is used by languages like Solidity and Vyper, where we expect this improvement to provide efficient means of building
data structures, including efficient sliced access and copies of memory objects. Having a dedicated &lt;code&gt;MCOPY&lt;&#x2F;code&gt; instruction would also add
forward protection against future gas cost changes to &lt;code&gt;CALL&lt;&#x2F;code&gt; instructions in general.&lt;&#x2F;p&gt;
&lt;p&gt;Having a special &lt;code&gt;MCOPY&lt;&#x2F;code&gt; instruction makes the job of static analyzers and optimizers easier, since the effects of a &lt;code&gt;CALL&lt;&#x2F;code&gt; in general
have to be fenced, whereas an &lt;code&gt;MCOPY&lt;&#x2F;code&gt; instruction would be known to only have memory effects. Even if special cases are added
for precompiles, a future hard fork could change &lt;code&gt;CALL&lt;&#x2F;code&gt; effects, and so any analysis of code using the identity precompile would only
be valid for a certain range of blocks.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we expect memory copying to be immensely useful for various computationally heavy operations, such as EVM384,
where it is identified as a significant overhead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The instruction &lt;code&gt;MCOPY&lt;&#x2F;code&gt; is introduced at &lt;code&gt;0x5E&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;input-stack&quot;&gt;Input stack&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Stack&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;top - 0&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;dst&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;top - 1&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;src&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;top - 2&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;length&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;This ordering matches the other copying instructions, i.e. &lt;code&gt;CALLDATACOPY&lt;&#x2F;code&gt;, &lt;code&gt;RETURNDATACOPY&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-costs&quot;&gt;Gas costs&lt;&#x2F;h3&gt;
&lt;p&gt;Per yellow paper terminology, it should be considered part of the &lt;code&gt;W_copy&lt;&#x2F;code&gt; group of opcodes, and follow the gas calculation for &lt;code&gt;W_copy&lt;&#x2F;code&gt; in the yellow paper. While the calculation in the yellow paper should be considered the final word, for reference, as of time of this writing, that currently means its gas cost is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;words_copied = (length + 31) &#x2F;&#x2F; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g_verylow    = 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g_copy       = 3 * words_copied + memory_expansion_cost&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gas_cost     = g_verylow + g_copy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;output-stack&quot;&gt;Output stack&lt;&#x2F;h3&gt;
&lt;p&gt;This instruction returns no stack items.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;semantics&quot;&gt;Semantics&lt;&#x2F;h3&gt;
&lt;p&gt;It copies &lt;code&gt;length&lt;&#x2F;code&gt; bytes from the offset pointed at &lt;code&gt;src&lt;&#x2F;code&gt; to the offset pointed at &lt;code&gt;dst&lt;&#x2F;code&gt; in memory.
Copying takes place as if an intermediate buffer was used, allowing the destination and source to overlap.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;length &amp;gt; 0&lt;&#x2F;code&gt; and (&lt;code&gt;src + length&lt;&#x2F;code&gt; or &lt;code&gt;dst + length&lt;&#x2F;code&gt;) is beyond the current memory length, the memory is extended with respective gas cost applied.&lt;&#x2F;p&gt;
&lt;p&gt;The gas cost of this instruction mirrors that of other &lt;code&gt;Wcopy&lt;&#x2F;code&gt; instructions and is &lt;code&gt;Gverylow + Gcopy * ceil(length &#x2F; 32)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Production implementation of exact-word memory copying and partial-word memory copying can be found in the Solidity, Vyper and Fe compilers.&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; the call overhead using the identity precompile was reduced from 700 to 100 gas.
This is still prohibitive for making the precompile a reasonable alternative again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a new instruction which did not exist previously. Already deployed contracts using this instruction could change their behaviour after this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;MCOPY 0 32 32&lt;&#x2F;code&gt; - copy 32 bytes from offset 32 to offset 0.&lt;&#x2F;p&gt;
&lt;p&gt;pre (spaces included for readability):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000000 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;post:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;gas used: 6&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;MCOPY 0 0 32&lt;&#x2F;code&gt; - copy 32 bytes from offset 0 to offset 0.&lt;&#x2F;p&gt;
&lt;p&gt;pre:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0101010101010101010101010101010101010101010101010101010101010101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;post:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0101010101010101010101010101010101010101010101010101010101010101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;gas used: 6&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;MCOPY 0 1 8&lt;&#x2F;code&gt; - copy 8 bytes from offset 1 to offset 0 (overlapping).&lt;&#x2F;p&gt;
&lt;p&gt;pre (space at byte 8):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0001020304050607 080000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;post:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0102030405060708 080000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;gas used: 6&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;MCOPY 1 0 8&lt;&#x2F;code&gt; - copy 8 bytes from offset 0 to offset 1 (overlapping).&lt;&#x2F;p&gt;
&lt;p&gt;pre (space at byte 8):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0001020304050607 080000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;post:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000010203040506 070000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;gas used: 6&lt;&#x2F;p&gt;
&lt;h3 id=&quot;full-test-suite&quot;&gt;Full test suite&lt;&#x2F;h3&gt;
&lt;p&gt;A full suite of tests can be found in the execution spec tests: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;tree&#x2F;c0065176a79f89d93f4c326186fc257ec5b8d5f1&#x2F;tests&#x2F;cancun&#x2F;eip5656_mcopy&quot;&gt;MCOPY suite&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Clients should take care that their implementation does not use an intermediate buffer (see for instance that the C stdlib &lt;code&gt;memmove&lt;&#x2F;code&gt; function does not use an intermediate buffer), as this is a potential Denial of Service (DoS) vector. Most language builtins &#x2F; standard library functions for moving bytes have the correct performance characteristics here.&lt;&#x2F;p&gt;
&lt;p&gt;This aside, the analysis for Denial of Service (DoS) and memory exhaustion attacks is identical to other opcodes which touch memory, as the memory expansion follows the same pricing rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Deposit Contract Snapshot Interface</title>
        <published>2021-01-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Mark Mackey</name><uri>https://github.com/ethDreamer</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4881/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-4881-deposit-contract-snapshot-interface/8554" />
        

        <id>https://wg-eips.ritovision.com/4881/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:4881"
            label="EIP-4881" />
        

        
        

        
        <summary type="html">Establishing the format and endpoint for transmitting a snapshot of the deposit Merkle tree</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4881/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a standard format for transmitting the deposit contract Merkle tree in a compressed form during weak subjectivity sync. This allows newly syncing consensus clients to reconstruct the deposit tree much faster than downloading all historical deposits. The format proposed also allows clients to prune deposits that are no longer needed to participate fully in consensus (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#deposit-finalization-flow&quot;&gt;Deposit Finalization Flow&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;To reconstruct the deposit Merkle tree, most client implementations require beacon nodes to download and store every deposit log since the launch of the deposit contract. However, this approach requires beacon nodes to store far more deposits than necessary to participate in consensus. Additionally, this leads to increased sync times for new nodes, which is particularly evident during weak subjectivity sync. This simplistic approach also prevents historical contract logs from being pruned from full nodes, a prospect frequently discussed in the context of limiting state growth.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Consensus clients MAY continue to implement the deposit Merkle tree however they choose. However, when transmitting the tree to newly syncing nodes, clients MUST use the following format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    finalized&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_count&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    execution_block_hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    execution_block_height&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;finalized&lt;&#x2F;code&gt; is a variable-length list (of maximum size &lt;code&gt;DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;code&gt;) containing the hashes defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#deposit-finalization-flow&quot;&gt;Deposit Finalization Flow&lt;&#x2F;a&gt; section below. The fields &lt;code&gt;deposit_root&lt;&#x2F;code&gt;, &lt;code&gt;deposit_count&lt;&#x2F;code&gt;, and &lt;code&gt;execution_block_hash&lt;&#x2F;code&gt; store the same information as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;2b45496fe48fa75450ad29a05bdd48866f86528a&#x2F;specs&#x2F;phase0&#x2F;beacon-chain.md#eth1data&quot;&gt;&lt;code&gt;Eth1Data&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; object that corresponds to the snapshot, and &lt;code&gt;execution_block_height&lt;&#x2F;code&gt; is the height of the execution block with hash &lt;code&gt;execution_block_hash&lt;&#x2F;code&gt;. Consensus clients MUST make this structure available via the Beacon Node API endpoint:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;eth&#x2F;v1&#x2F;beacon&#x2F;deposit_snapshot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;deposit-finalization-flow&quot;&gt;Deposit Finalization Flow&lt;&#x2F;h3&gt;
&lt;p&gt;During deposit processing, the beacon chain requires deposits to be submitted along with a Merkle path to the deposit root. This is required exactly once for each deposit. When a deposit has been processed by the beacon chain and the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#deposit-finalization-conditions&quot;&gt;deposit finalization conditions&lt;&#x2F;a&gt; have been met, many of the hashes along the path to the deposit root will never be required again to construct Merkle proofs on chain. These unnecessary hashes MAY be pruned to save space. The image below illustrates the evolution of the deposit Merkle tree under this process alongside the corresponding &lt;code&gt;DepositTreeSnapshot&lt;&#x2F;code&gt; as new deposits are added and older deposits become finalized:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;.&#x2F;assets&#x2F;deposit_tree_evolution.svg&quot; alt=&quot;deposit tree evolution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The format in this specification was chosen to achieve several goals simultaneously:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Enable reconstruction of the deposit contract Merkle tree without requiring full nodes to store all historical contract logs&lt;&#x2F;li&gt;
&lt;li&gt;Avoid requiring consensus nodes to retain more deposits than necessary to fully participate in consensus&lt;&#x2F;li&gt;
&lt;li&gt;Simplicity of implementation (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;a&gt; section)&lt;&#x2F;li&gt;
&lt;li&gt;Increase speed of weak subjectivity sync&lt;&#x2F;li&gt;
&lt;li&gt;Compatibility with existing implementations of this mechanism (see discussion)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The proposed &lt;code&gt;DepositTreeSnapshot&lt;&#x2F;code&gt; structure includes both &lt;code&gt;execution_block_hash&lt;&#x2F;code&gt; and &lt;code&gt;execution_block_height&lt;&#x2F;code&gt; for convenience to consensus node implementors. While only one of these fields is strictly necessary, different clients may have already designed their block cache logic around one or the other. Sending only one of these would force some consensus clients to query the execution engine for the other information, but as this is happening in the context of a newly syncing consensus node, it is very likely that the execution engine will not be synced, especially post-merge. The &lt;code&gt;deposit_root&lt;&#x2F;code&gt; field is also not strictly necessary, but by including it, newly syncing consensus nodes can cheaply validate any received snapshot against itself (see the &lt;code&gt;calculate_root()&lt;&#x2F;code&gt; method in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-reconstruct-the-tree-directly-from-the-deposit-contract&quot;&gt;Why not Reconstruct the Tree Directly from the Deposit Contract?&lt;&#x2F;h3&gt;
&lt;p&gt;The deposit contract can only provide the tree at the head of the chain. Because the beacon chain&#x27;s view of the deposit contract lags behind the execution chain by &lt;code&gt;ETH1_FOLLOW_DISTANCE&lt;&#x2F;code&gt;, there are almost always deposits which haven&#x27;t yet been included in the chain that need proofs constructed from an earlier version of the tree than exists at the head.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-reconstruct-the-tree-from-a-deposit-in-the-beacon-chain&quot;&gt;Why not Reconstruct the Tree from a Deposit in the Beacon Chain?&lt;&#x2F;h3&gt;
&lt;p&gt;In principle, a node could scan backwards through the chain starting from the weak subjectivity checkpoint to locate a suitable &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;2b45496fe48fa75450ad29a05bdd48866f86528a&#x2F;specs&#x2F;phase0&#x2F;beacon-chain.md#deposit&quot;&gt;&lt;code&gt;Deposit&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, and then extract the rightmost branch of the tree from that. The node would also need to extract the &lt;code&gt;execution_block_hash&lt;&#x2F;code&gt; from which to start syncing new deposits from the &lt;code&gt;Eth1Data&lt;&#x2F;code&gt; in the corresponding &lt;code&gt;BeaconState&lt;&#x2F;code&gt;. This approach is less desirable for a few reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;More difficult to implement due to the edge cases involved in finding a suitable deposit to anchor to (the rightmost branch of the latest not-yet-included deposit is required)&lt;&#x2F;li&gt;
&lt;li&gt;This would make backfilling beacon blocks a requirement for reconstructing the deposit tree and therefore a requirement for block production&lt;&#x2F;li&gt;
&lt;li&gt;This is inherently slower than getting this information from the weak subjectivity checkpoint&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backwards compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases are included in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;.&#x2F;assets&#x2F;test_cases.yaml&quot;&gt;test_cases.yaml&lt;&#x2F;a&gt;. Each case is structured as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DepositTestCase&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; DepositData&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; These are all the inputs to the deposit contract&amp;#39;s deposit() function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_data_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The tree hash root of this deposit (calculated for convenience)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    eth1_data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Eth1Data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;           #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An Eth1Data object that can be used to finalize the tree after pushing this deposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block_height&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;          #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The height of the execution block with this Eth1Data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    snapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The resulting DepositTreeSnapshot object if the tree were finalized after this deposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This EIP also includes other files for testing:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;.&#x2F;assets&#x2F;deposit_snapshot.py&quot;&gt;deposit_snapshot.py&lt;&#x2F;a&gt; contains the same code as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;.&#x2F;assets&#x2F;eip_4881.py&quot;&gt;eip_4881.py&lt;&#x2F;a&gt; contains boilerplate declarations&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;.&#x2F;assets&#x2F;test_deposit_snapshot.py&quot;&gt;test_deposit_snapshot.py&lt;&#x2F;a&gt; includes code for running test cases against the reference implementation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If these files are downloaded to the same directory, the test cases can be run by executing &lt;code&gt;pytest&lt;&#x2F;code&gt; in that directory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;This implementation lacks full error checking and is optimized for readability over efficiency. If &lt;code&gt;tree&lt;&#x2F;code&gt; is a &lt;code&gt;DepositTree&lt;&#x2F;code&gt;, then the &lt;code&gt;DepositTreeSnapshot&lt;&#x2F;code&gt; can be obtained by calling &lt;code&gt;tree.get_snapshot()&lt;&#x2F;code&gt; and a new instance of the tree can be recovered from the snapshot by calling &lt;code&gt;DepositTree.from_snapshot()&lt;&#x2F;code&gt;. See the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#deposit-finalization-conditions&quot;&gt;Deposit Finalization Conditions&lt;&#x2F;a&gt; section for discussion on when the tree can be pruned by calling &lt;code&gt;tree.finalize()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Generating proofs for deposits against an earlier version of the tree is relatively fast in this implementation; just create a copy of the finalized tree with &lt;code&gt;copy = DepositTree.from_snapshot(tree.get_snapshot())&lt;&#x2F;code&gt; and then append the remaining deposits to the desired count with &lt;code&gt;copy.push_leaf(deposit)&lt;&#x2F;code&gt;. Proofs can then be obtained with &lt;code&gt;copy.get_proof(index)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt; __future__&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; annotations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Optional&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; dataclasses&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; eip_4881&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;to_le_bytes&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;zerohashes&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    finalized&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    deposit_count&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    execution_block_hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    execution_block_height&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calculate_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;                index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;span&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&gt;            size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; to_le_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; from_tree_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-parameter z-function&quot;&gt;                        deposit_count&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;                        execution_block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        snapshot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            finalized&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; deposit_count&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; execution_block&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; execution_block&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A real implementation should store the deposit_root from the eth1_data passed to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; DepositTree.finalize() instead of relying on calculate_root() here. This allows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the snapshot to be validated using calculate_root().&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calculate_root&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; snapshot&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DepositTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mix_in_length&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    finalized_execution_block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Optional&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; DepositTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        merkle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; DepositTree&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;merkle&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_snapshot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized_execution_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        finalized&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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&gt;        deposit_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_tree_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            finalized&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; deposit_count&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized_execution_block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; from_snapshot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;snapshot&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; DepositTreeSnapshot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; DepositTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; decent validation check on the snapshot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;calculate_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        finalized_execution_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;execution_block_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;execution_block_height&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tree&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_snapshot_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; DepositTree&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; snapshot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; finalized_execution_block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; eth1_data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Eth1Data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; execution_block_height&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalized_execution_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;eth1_data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;block_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; execution_block_height&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;eth1_data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_proof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mix_in_length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ensure index &amp;gt; finalized deposit index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        leaf&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;generate_proof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;to_le_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mix_in_length&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; leaf&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; to_le_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mix_in_length&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; leaf&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mix_in_length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaf&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;        pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; leaf&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; returns the number of finalized deposits in the tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; while populating result with the finalized hashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;leaves&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; depth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaves&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Zero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;depth&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;depth&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaves&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;        split&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaves&lt;&#x2F;span&gt;&lt;span&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&gt;        left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaves&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaves&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; Node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; from_snapshot_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; deposits&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposits&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; empty tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Zero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposits&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; finalized&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;        left_subtree&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; left_subtree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_snapshot_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Zero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;            left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left_subtree&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; finalized&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;            right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;from_snapshot_parts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;finalized&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; left_subtree&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; generate_proof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; depth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&gt;        proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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&gt;        node&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            ith_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; ith_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;                proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;                node&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; node&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;                proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;                node&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; node&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        proof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reverse&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; node&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; proof&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;MerkleTree&lt;&#x2F;span&gt;&lt;span&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&gt;    deposit_count&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&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&gt;        result&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;deposit_count&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;MerkleTree&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; Finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;MerkleTree&lt;&#x2F;span&gt;&lt;span&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&gt;    left&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    right&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_full&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; leaf&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaf&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&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 class=&quot;z-variable z-language&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;leaf&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;level&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; Finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposits&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;deposits_to_finalize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            remaining&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; deposits_to_finalize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;finalize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;remaining&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result&lt;&#x2F;span&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Zero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt;MerkleTree&lt;&#x2F;span&gt;&lt;span&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&gt;    n&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_root&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; DEPOSIT_CONTRACT_DEPTH&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the entirely empty tree case. This is included for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; consistency&#x2F;clarity as the zerohashes array is typically&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only defined from 0 to DEPOSIT_CONTRACT_DEPTH - 1.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; sha256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; zerohashes&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is_full&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; push_leaf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; leaf&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Hash32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; MerkleTree&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;leaf&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get_finalized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Hash32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;relying-on-weak-subjectivity-sync&quot;&gt;Relying on Weak Subjectivity Sync&lt;&#x2F;h3&gt;
&lt;p&gt;The upcoming switch to PoS will require newly synced nodes to rely on valid weak subjectivity checkpoints because of long-range attacks. This proposal relies on the weak subjectivity assumption that clients will not bootstrap with an invalid WS checkpoint.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deposit-finalization-conditions&quot;&gt;Deposit Finalization Conditions&lt;&#x2F;h3&gt;
&lt;p&gt;Care must be taken not to send a snapshot which includes deposits that haven&#x27;t been fully included in the finalized checkpoint. Let &lt;code&gt;state&lt;&#x2F;code&gt; be the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;2b45496fe48fa75450ad29a05bdd48866f86528a&#x2F;specs&#x2F;phase0&#x2F;beacon-chain.md#beaconstate&quot;&gt;&lt;code&gt;BeaconState&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; at a given block in the chain. Under normal operation, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;consensus-specs&#x2F;blob&#x2F;2b45496fe48fa75450ad29a05bdd48866f86528a&#x2F;specs&#x2F;phase0&#x2F;beacon-chain.md#eth1data&quot;&gt;&lt;code&gt;Eth1Data&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; stored in &lt;code&gt;state.eth1_data&lt;&#x2F;code&gt; is replaced every &lt;code&gt;EPOCHS_PER_ETH1_VOTING_PERIOD&lt;&#x2F;code&gt; epochs. Thus, finalization of the deposit tree proceeds with increments of &lt;code&gt;state.eth1_data&lt;&#x2F;code&gt;. Let &lt;code&gt;eth1data&lt;&#x2F;code&gt; be some &lt;code&gt;Eth1Data&lt;&#x2F;code&gt;. Both of the following conditions MUST be met to consider &lt;code&gt;eth1data&lt;&#x2F;code&gt; finalized:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A finalized checkpoint exists where the corresponding &lt;code&gt;state&lt;&#x2F;code&gt; has &lt;code&gt;state.eth1_data == eth1data&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A finalized checkpoint exists where the corresponding &lt;code&gt;state&lt;&#x2F;code&gt; has &lt;code&gt;state.eth1_deposit_index &amp;gt;= eth1data.deposit_count&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;When these conditions are met, the tree can be pruned in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4881&#x2F;#reference-implementation&quot;&gt;reference implementation&lt;&#x2F;a&gt; by calling &lt;code&gt;tree.finalize(eth1data, execution_block_height)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>BASEFEE opcode</title>
        <published>2021-01-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Abdelhamid Bakhta</name><uri>https://github.com/abdelhamidbakhta</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3198/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3198-basefeeopcode/5162" />
        

        <id>https://wg-eips.ritovision.com/3198/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:3198"
            label="EIP-3198" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3198/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Adds an opcode that gives the EVM access to the block&#x27;s base fee.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add a &lt;code&gt;BASEFEE (0x48)&lt;&#x2F;code&gt; that returns the value of the base fee of the current block it is executing in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The intended use case would be for contracts to get the value of the base fee. This feature would enable or improve existing use cases, such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Contracts that need to set bounties for anyone to &quot;poke&quot; them with a transaction could set the bounty to be &lt;code&gt;BASEFEE + x&lt;&#x2F;code&gt;, or &lt;code&gt;BASEFEE * (1 + x)&lt;&#x2F;code&gt;. This makes the mechanism more reliable, because they will always pay &quot;enough&quot; regardless of market conditions.&lt;&#x2F;li&gt;
&lt;li&gt;Gas futures can be implemented based on it. This would be more precise than gastokens.&lt;&#x2F;li&gt;
&lt;li&gt;Improve the security for state channels, plasma, optirolls and other fraud proof driven solutions. Having the &lt;code&gt;BASEFEE&lt;&#x2F;code&gt; as an input allows you to lengthen the challenge period automatically if you see that the &lt;code&gt;BASEFEE&lt;&#x2F;code&gt; is high.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Add a &lt;code&gt;BASEFEE&lt;&#x2F;code&gt; opcode at &lt;code&gt;(0x48)&lt;&#x2F;code&gt;, with gas cost &lt;code&gt;G_base&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;|  Op  	| Input 	| Output 	| Cost 	|
|:----:	|:-----:	|:------:	|:----:	|
| 0x48 	|   0   	|    1   	|   2  	|&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gas-cost&quot;&gt;Gas cost&lt;&#x2F;h3&gt;
&lt;p&gt;The value of the base fee is needed to process transactions. That means it&#x27;s value is already available before running the EVM code.
The opcode does not add extra complexity and additional read&#x2F;write operations, hence the choice of &lt;code&gt;G_base&lt;&#x2F;code&gt; gas cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no known backward compatibility issues with this opcode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;nominal-case&quot;&gt;Nominal case&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming current block base fee is &lt;code&gt;7 wei&lt;&#x2F;code&gt;.
This should push the value &lt;code&gt;7&lt;&#x2F;code&gt; (left padded byte32) to the stack.&lt;&#x2F;p&gt;
&lt;p&gt;Bytecode: &lt;code&gt;0x4800&lt;&#x2F;code&gt; (&lt;code&gt;BASEFEE, STOP&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pc&lt;&#x2F;th&gt;&lt;th&gt;Op&lt;&#x2F;th&gt;&lt;th&gt;Cost&lt;&#x2F;th&gt;&lt;th&gt;Stack&lt;&#x2F;th&gt;&lt;th&gt;RStack&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;BASEFEE&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;STOP&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;[7]&lt;&#x2F;td&gt;&lt;td&gt;[]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Output: 0x
Consumed gas: &lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The value of the base fee is not sensitive and is publicly accessible in the block header. There are no known security implications with this opcode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Semi-Fungible Token</title>
        <published>2020-12-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Will Wang</name><uri>https://github.com/will42w</uri>
	</author>
	
	<author>
		<name>Mike Meng</name><email>myan@solv.finance</email>
	</author>
	
	<author>
		<name>Yi Cai</name><uri>https://github.com/YeeTsai</uri><email>yee.tsai@gmail.com</email>
	</author>
	
	<author>
		<name>Ryan Chow</name><email>ryanchow@solv.finance</email>
	</author>
	
	<author>
		<name>Zhongxin Wu</name><uri>https://github.com/Nerverwind</uri>
	</author>
	
	<author>
		<name>AlvisDu</name><uri>https://github.com/AlvisDu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3525/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-3525-the-semi-fungible-token" />
        

        <id>https://wg-eips.ritovision.com/3525/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:3525"
            label="ERC-3525" />
        

        
        

        
        <summary type="html">Defines a specification where ERC-721 compatible tokens with the same SLOT and different IDs are fungible.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3525/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This is a standard for semi-fungible tokens. The set of smart contract interfaces described in this document defines an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; compatible token standard. This standard introduces an &lt;code&gt;&amp;lt;ID, SLOT, VALUE&amp;gt;&lt;&#x2F;code&gt; triple scalar model that represents the semi-fungible structure of a token. It also introduces new transfer models as well as approval models that reflect the semi-fungible nature of the tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Token contains an ERC-721 equivalent ID property to identify itself as a universally unique entity, so that the tokens can be transferred between addresses and approved to be operated in ERC-721 compatible way.&lt;&#x2F;p&gt;
&lt;p&gt;Token also contains a &lt;code&gt;value&lt;&#x2F;code&gt; property, representing the quantitative nature of the token. The meaning of the &#x27;value&#x27; property is quite like that of the &#x27;balance&#x27; property of an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token. Each token has a &#x27;slot&#x27; attribute, ensuring that the value of two tokens with the same slot be treated as fungible, adding fungibility to the value property of the tokens.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP introduces new token transfer models for semi-fungibility, including value transfer between two tokens of the same slot and value transfer from a token to an address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Tokenization is one of the most important trends by which to use and control digital assets in crypto. Traditionally, there have been two approaches to do so: fungible and non-fungible tokens. Fungible tokens generally use the ERC-20 standard, where every unit of an asset is identical to each other. ERC-20 is a flexible and efficient way to manipulate fungible tokens. Non-fungible tokens are predominantly ERC-721 tokens, a standard capable of distinguishing digital assets from one another based on identity.&lt;&#x2F;p&gt;
&lt;p&gt;However, both have significant drawbacks. For example, ERC-20 requires that users create a separate ERC-20 contract for each individual data structure or combination of customizable properties. In practice, this results in an extraordinarily large amount of ERC-20 contracts that need to be created. On the other hand, ERC-721 tokens provide no quantitative feature, significantly undercutting their computability, liquidity, and manageability. For example, if one was to create financial instruments such as bonds, insurance policy, or vesting plans using ERC-721, no standard interfaces are available for us to control the value in them, making it impossible, for example, to transfer a portion of the equity in the contract represented by the token.&lt;&#x2F;p&gt;
&lt;p&gt;A more intuitive and straightforward way to solve the problem is to create a semi-fungible token that has the quantitative features of ERC-20 and qualitative attributes of ERC-721. The backwards-compatibility with ERC-721 of such semi-fungible tokens would help utilize existing infrastructures already in use and lead to faster adoption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Every &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3525&#x2F;&quot;&gt;ERC-3525&lt;&#x2F;a&gt; compliant contract must implement the ERC-3525, ERC-721 and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-3525 Semi-Fungible Token Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xd5358140.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is IERC165, IERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when value of a token is transferred to another token with the same slot,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  including zero value transfers (_value == 0) as well as transfers when tokens are created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  (`_fromTokenId` == 0) or destroyed (`_toTokenId` == 0).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token id to transfer value from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token id to transfer value to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The transferred value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferValue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when the approval value of a token is set or &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator to approve for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The maximum value that `_operator` is allowed to manage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalValue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when the slot of a token is set or &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token of which slot is set or &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _oldSlot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The previous slot of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newSlot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The updated slot of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; SlotChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _oldSlot&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _newSlot&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the number of decimals the token uses for value - e.g. 6, means the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  representation of the value of a token can be calculated by dividing it by 1,000,000.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  Considering the compatibility with third-party wallets, this function is defined as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `valueDecimals()` instead of `decimals()` to avoid conflict with ERC-20 tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; number of decimals for value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; valueDecimals&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the value of a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token for which to query the balance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; value of `_tokenId`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the slot of a token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; slot of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; slotOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Allow an operator to manage the value of a token, up to the `_value`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST revert unless caller is the current owner, an authorized operator, or the approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  address for `_tokenId`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST emit the ApprovalValue event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator to be approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The maximum value of `_toTokenId` that `_operator` is allowed to manage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the maximum value of a token that an operator is allowed to manage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token for which to query the allowance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of an operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; current approval value of `_tokenId` that `_operator` is allowed to manage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer value from a specified token to another specified token with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Caller MUST be the current owner, an authorized operator or an operator who has been&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  approved the whole `_fromTokenId` or part of it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if `_fromTokenId` or `_toTokenId` is zero token id or does not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if slots of `_fromTokenId` and `_toTokenId` do not match.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if `_value` exceeds the balance of `_fromTokenId` or its allowance to the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST emit `TransferValue` event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to transfer value from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to transfer value to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The transferred value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer value from a specified token to an address. The caller should confirm that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `_to` is capable of receiving ERC-3525 tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function MUST create a new ERC-3525 token with the same slot for `_to`, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  or find an existing token with the same slot owned by `_to`, to receive the transferred value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if `_fromTokenId` is zero token id or does not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if `_to` is zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert if `_value` exceeds the balance of `_fromTokenId` or its allowance to the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  operator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST emit `Transfer` and `TransferValue` events.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token to transfer value from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address to transfer value to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The transferred value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the token which receives the transferred value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The slot&#x27;s enumeration extension is OPTIONAL. This allows your contract to publish its full list of &lt;code&gt;SLOT&lt;&#x2F;code&gt;s and make them discoverable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-3525 Semi-Fungible Token Standard, optional extension for slot enumeration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interfaces for any contract that wants to support enumeration of slots as well as tokens &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x3b741b9e.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525SlotEnumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* , &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC721Enumerable&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F; &lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the total amount of slots stored by the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; total amount of slots&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; slotCount&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the slot at the specified index of all slots stored by the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index in the slot list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; slot at `index` of all slots.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; slotByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the total amount of tokens with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The slot to query token supply for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; total amount of tokens with the specified `_slot`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenSupplyInSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the token at the specified index of all tokens with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The slot to query tokens with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The index in the token list of the slot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token ID at `_index` of all tokens with `_slot`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenInSlotByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The slot level approval is OPTIONAL. This allows any contract that wants to support approval for slots, which allows an operator to manage one&#x27;s tokens with the same slot.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-3525 Semi-Fungible Token Standard, optional extension for approval of slot level&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interfaces for any contract that wants to support approval of slot level, which allows an&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  operator to manage one&amp;#39;s tokens with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3525&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xb688be58.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525SlotApprovable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when an operator is approved or disapproved to manage all of `_owner`&amp;#39;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  tokens with the same slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address whose tokens are approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The slot to approve, all of `_owner`&amp;#39;s tokens with this slot are approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The operator being approved or disapproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identify if `_operator` is approved or disapproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approve or disapprove an operator to manage all of `_owner`&amp;#39;s tokens with the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  specified slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Caller SHOULD be `_owner` or an operator who has been authorized through&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `setApprovalForAll`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST emit ApprovalSlot event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that owns the ERC-3525 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The slot of tokens being queried approval of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address for whom to query approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Identify if `_operator` would be approved or disapproved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if `_operator` is authorized to manage all of `_owner`&amp;#39;s tokens with the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  specified slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that owns the ERC-3525 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The slot of tokens being queried approval of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address for whom to query approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if `_operator` is authorized to manage all of `_owner`&amp;#39;s tokens with `_slot`,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-3525-token-receiver&quot;&gt;ERC-3525 Token Receiver&lt;&#x2F;h3&gt;
&lt;p&gt;If a smart contract wants to be informed when they receive values from other addresses, it should implement all of the functions in the &lt;code&gt;IERC3525Receiver&lt;&#x2F;code&gt; interface, in the implementation it can decide whether to accept or reject the transfer. See &quot;Transfer Rules&quot; for further detail.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt; pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-3525 token receiver interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for a smart contract that wants to be informed by ERC-3525 contracts when receiving values from ANY addresses or ERC-3525 tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x009ce20b.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525Receiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the receipt of an ERC-3525 token value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An ERC-3525 smart contract MUST check whether this function is implemented by the recipient contract, if the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  recipient contract implements this function, the ERC-3525 contract MUST call this function after a &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  value transfer (i.e. `transferFrom(uint256,uint256,uint256,bytes)`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST return 0x009ce20b (i.e. `bytes4(keccak256(&amp;#39;onERC3525Received(address,uint256,uint256,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  uint256,bytes)&amp;#39;))`) if the transfer is accepted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  MUST revert or return any value other than 0x009ce20b if the transfer is rejected.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address which triggered the transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token id to transfer value from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token id to transfer value to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The transferred value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `bytes4(keccak256(&amp;#39;onERC3525Received(address,uint256,uint256,uint256,bytes)&amp;#39;))` &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  unless the transfer is rejected.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onERC3525Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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;&#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;h3 id=&quot;token-manipulation&quot;&gt;Token Manipulation&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;scenarios&quot;&gt;Scenarios&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Transfer:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Besides ERC-721 compatible token transfer methods, this EIP introduces two new transfer models: value transfer from ID to ID, and value transfer from ID to address.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _toTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toTokenId_&lt;&#x2F;span&gt;&lt;span&gt;)&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 one allows value transfers from one token (specified by &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt;) to another token (specified by &lt;code&gt;_toTokenId&lt;&#x2F;code&gt;) within the same slot, resulting in the &lt;code&gt;_value&lt;&#x2F;code&gt; being subtracted from the value of the source token and added to the value of the destination token;&lt;&#x2F;p&gt;
&lt;p&gt;The second one allows value transfers from one token (specified by &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt;) to an address (specified by &lt;code&gt;_to&lt;&#x2F;code&gt;), the value is actually transferred to a token owned by the address, and the id of the destination token should be returned. Further explanation can be found in the &#x27;design decision&#x27; section for this method.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;rules&quot;&gt;Rules&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;approving rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This EIP provides four kinds of approving functions indicating different levels of approvals, which can be described as full level approval, slot level approval, token ID level approval as well as value level approval.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt;, compatible with ERC-721, SHOULD indicate the full level of approval, which means that the authorized operators are capable of managing all the tokens, including their values, owned by the owner.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;setApprovalForSlot&lt;&#x2F;code&gt; (optional) SHOULD indicate the slot level of approval, which means that the authorized operators are capable of managing all the tokens with the specified slot, including their values, owned by the owner.&lt;&#x2F;li&gt;
&lt;li&gt;The token ID level &lt;code&gt;approve&lt;&#x2F;code&gt; function, compatible with ERC-721, SHOULD indicate that the authorized operator is capable of managing only the specified token ID, including its value, owned by the owner.&lt;&#x2F;li&gt;
&lt;li&gt;The value level &lt;code&gt;approve&lt;&#x2F;code&gt; function, SHOULD indicate that the authorized operator is capable of managing the specified maximum value of the specified token owned by the owner.&lt;&#x2F;li&gt;
&lt;li&gt;For any approving function, the caller MUST be the owner or has been approved with a higher level of authority.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;transferFrom rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;transferFrom(uint256 _fromTokenId, uint256 _toTokenId, uint256 _value)&lt;&#x2F;code&gt; function, SHOULD indicate value transfers from one token to another token, in accordance with the rules below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST revert unless &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the owner of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt;, an authorized operator or an operator who has been approved the whole token or at least &lt;code&gt;_value&lt;&#x2F;code&gt; of it.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt; or &lt;code&gt;_toTokenId&lt;&#x2F;code&gt; is zero token id or does not exist.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if slots of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt; and &lt;code&gt;_toTokenId&lt;&#x2F;code&gt; do not match.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_value&lt;&#x2F;code&gt; exceeds the value of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt; or its allowance to the operator.&lt;&#x2F;li&gt;
&lt;li&gt;MUST check for the &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; function if the owner of _toTokenId is a smart contract, if the function exists, MUST call this function after the value transfer, MUST revert if the result is not equal to 0x009ce20b;&lt;&#x2F;li&gt;
&lt;li&gt;MUST emit &lt;code&gt;TransferValue&lt;&#x2F;code&gt; event.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;transferFrom(uint256 _fromTokenId, address _to, uint256 _value)&lt;&#x2F;code&gt; function, which transfers value from one token ID to an address, SHOULD follow the rule below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MUST either find a ERC-3525 token owned by the address &lt;code&gt;_to&lt;&#x2F;code&gt; or create a new ERC-3525 token, with the same slot of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt;, to receive the transferred value.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert unless &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the owner of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt;, an authorized operator or an operator who has been approved the whole token or at least &lt;code&gt;_value&lt;&#x2F;code&gt; of it.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt; is zero token id or does not exist.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_to&lt;&#x2F;code&gt; is zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_value&lt;&#x2F;code&gt; exceeds the value of &lt;code&gt;_fromTokenId&lt;&#x2F;code&gt; or its allowance to the operator.&lt;&#x2F;li&gt;
&lt;li&gt;MUST check for the &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; function if the _to address is a smart contract, if the function exists, MUST call this function after the value transfer, MUST revert if the result is not equal to 0x009ce20b;&lt;&#x2F;li&gt;
&lt;li&gt;MUST emit &lt;code&gt;Transfer&lt;&#x2F;code&gt; and &lt;code&gt;TransferValue&lt;&#x2F;code&gt; events.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;metadata&quot;&gt;Metadata&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;metadata-extensions&quot;&gt;Metadata Extensions&lt;&#x2F;h4&gt;
&lt;p&gt;ERC-3525 metadata extensions are compatible ERC-721 metadata extensions.&lt;&#x2F;p&gt;
&lt;p&gt;This optional interface can be identified with the ERC-165 Standard Interface Detection.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-3525 Semi-Fungible Token Standard, optional extension for metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interfaces for any contract that wants to support query of the Uniform Resource Identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  (URI) for the ERC-3525 contract as well as a specified slot. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  Because of the higher reliability of data stored in smart contracts compared to data stored in &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  centralized systems, it is recommended that metadata, including `contractURI`, `slotURI` and &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  `tokenURI`, be directly returned in JSON format, instead of being returned with a url pointing &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  to any resource stored in a centralized system. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3525&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xe1600902.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC3525Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    IERC3525&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;* , &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IERC721Metadata&lt;&#x2F;span&gt;&lt;span&gt; *&#x2F;&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the Uniform Resource Identifier (URI) for the current ERC-3525 contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function SHOULD return the URI for this contract in JSON format, starting with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  header `data:application&#x2F;json;`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3525 for the JSON schema for contract URI.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; JSON formatted URI of the current ERC-3525 contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; contractURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the Uniform Resource Identifier (URI) for the specified slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This function SHOULD return the URI for `_slot` in JSON format, starting with header&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  `data:application&#x2F;json;`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *  See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-3525 for the JSON schema for slot URI.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; JSON formatted URI of `_slot`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; slotURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;erc-3525-metadata-uri-json-schema&quot;&gt;ERC-3525 Metadata URI JSON Schema&lt;&#x2F;h4&gt;
&lt;p&gt;This is the &quot;ERC-3525 Metadata JSON Schema for &lt;code&gt;contractURI()&lt;&#x2F;code&gt;&quot; referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Optional. Either a base64 encoded imgae data or a URI pointing to a resource with mime type image&#x2F;* representing what this contract represents.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;external_link&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Optional. A URI pointing to an external resource.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;valueDecimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The number of decimal places that the balance should display - e.g. 18, means to divide the token value by 1000000000000000000 to get its user representation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;This is the &quot;ERC-3525 Metadata JSON Schema for &lt;code&gt;slotURI(uint)&lt;&#x2F;code&gt;&quot; referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Slot Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset category to which this slot represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset category to which this slot represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Optional. Either a base64 encoded imgae data or a URI pointing to a resource with mime type image&#x2F;* representing the asset category to which this slot represents.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Each item of `properties` SHOULD be organized in object format, including name, description, value, order (optional), display_type (optional), etc.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The name of this property.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes this property.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The value of this property, which may be a string or a number.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;is_intrinsic&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;According to the definition of `slot`, one of the best practice to generate the value of a slot is utilizing the `keccak256` algorithm to calculate the hash value of multi properties. In this scenario, the `properties` field should contain all the properties that are used to calculate the value of `slot`, and if a property is used in the calculation, is_intrinsic must be TRUE.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;order&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Optional, related to the value of is_intrinsic. If is_intrinsic is TRUE, it must be the order of this property appeared in the calculation method of the slot.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;display_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Optional. Specifies in what form this property should be displayed.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;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;This is the &quot;ERC-3525 Metadata JSON Schema for &lt;code&gt;tokenURI(uint)&lt;&#x2F;code&gt;&quot; referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Token Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Either a base64 encoded imgae data or a URI pointing to a resource with mime type image&#x2F;* representing the asset to which this token represents.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;THe value held by this token.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The id of the slot that this token belongs to.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Arbitrary properties. Values may be strings, numbers, objects or arrays. Optional, you can use the same schema as the properties section of ERC-3525 Metadata JSON Schema for slotURI(uint) if you need a better description attribute.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;metadata-generation&quot;&gt;Metadata generation&lt;&#x2F;h3&gt;
&lt;p&gt;This token standard is designed to represent semi-fungible assets, which are most suited for financial instruments rather than collectibles or in-game items. For maximum transparency and safety of digital assets, we strongly recommend that all implementations should generate metadata directly from contract code rather than giving out an off-chain server URL.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-decision-value-transfer-from-token-to-address&quot;&gt;Design decision: Value transfer from token to address&lt;&#x2F;h3&gt;
&lt;p&gt;The &#x27;value&#x27; of a token is a property of the token and is not linked to an address, so to transfer the value to an address would be actually transferring it to a token owned by that address, not the address itself.&lt;&#x2F;p&gt;
&lt;p&gt;From the implementation perspective, the process of transferring values from token to address could be done as follows: (1) create a new token for the recipient&#x27;s address, (2) transfer the value to the new token from the &#x27;source token&#x27;. So that this method is not fully independent from the ID-to-ID transfer method, and can be viewed as syntactic sugar that wraps the process described above.&lt;&#x2F;p&gt;
&lt;p&gt;In a special case, if the destination address owns one or more tokens with the same slot value as the source token, this method will have an alternative implementation as follows: (1) find one token owned by the address with the same slot value of the source token, (2) transfer the value to the found token.&lt;&#x2F;p&gt;
&lt;p&gt;Both implementations described above should be treated as compliant with this standard.&lt;&#x2F;p&gt;
&lt;p&gt;The purpose of maintaining id-to-address transfer function is to maximize the compatibility with most wallet apps, since for most of the token standards, the destination of token transfer are addresses. This syntactic wrapping will help wallet apps easily implement the value transfer function from a token to any address.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-decision-notification-acceptance-mechanism-instead-of-safe-transfer&quot;&gt;Design decision: Notification&#x2F;acceptance mechanism instead of &#x27;Safe Transfer&#x27;&lt;&#x2F;h3&gt;
&lt;p&gt;ERC-721 and some later token standards introduced &#x27;Safe Transfer&#x27; model, for better control of the &#x27;safety&#x27; when transferring tokens, this mechanism leaves the choice of different transfer modes (safe&#x2F;unsafe) to the sender, and may cause some potential problems:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;In most situations the sender does not know how to choose between two kinds of transfer methods (safe&#x2F;unsafe);&lt;&#x2F;li&gt;
&lt;li&gt;If the sender calls the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; method, the transfer may fail if the recipient contract did not implement the callback function, even if that contract is capable of receiving and manipulating the token without issue.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This EIP defines a simple &#x27;Check, Notify and Response&#x27; model for better flexibility as well as simplicity:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;No extra &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; methods are needed, all callers only need to call one kind of transfer;&lt;&#x2F;li&gt;
&lt;li&gt;All ERC-3525 contracts MUST check for the existence of &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; on the recipient contract and call the function when it exists;&lt;&#x2F;li&gt;
&lt;li&gt;Any smart contract can implement &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; function for the purpose of being notified after receiving values; this function MUST return 0x009ce20b (i.e. &lt;code&gt;bytes4(keccak256(&#x27;onERC3525Received(address,uint256,uint256,uint256,bytes)&#x27;))&lt;&#x2F;code&gt;) if the transfer is accepted, or any other value if the transfer is rejected.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There is a special case for this notification&#x2F;acceptance mechanism: since ERC-3525 allows value transfer from an address to itself, when a smart contract which implements &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; transfers value to itself, &lt;code&gt;onERC3525Received&lt;&#x2F;code&gt; will also be called. This allows for the contract to implement different rules of acceptance between self-value-transfer and receiving value from other addresses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-decision-relationship-between-different-approval-models&quot;&gt;Design decision: Relationship between different approval models&lt;&#x2F;h3&gt;
&lt;p&gt;For semantic compatibility with ERC-721 as well as the flexibility of value manipulation of tokens, we decided to define the relationships between some of the levels of approval like that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Approval of an id will lead to the ability to partially transfer values from this id by the approved operator; this will simplify the value approval for an id. However, the approval of total values in a token should not lead to the ability to transfer the token entity by the approved operator.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; will lead to the ability to partially transfer values from any token, as well as the ability to approve partial transfer of values from any token to a third party; this will simplify the value transfer and approval of all tokens owned by an address.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned in the beginning, this EIP is backward compatible with ERC-721.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3525&#x2F;.&#x2F;assets&#x2F;contracts&#x2F;ERC3525.sol&quot;&gt;ERC-3525 implementation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The value level approval and slot level approval (optional) is isolated from ERC-721 approval models, so that approving value should not affect ERC-721 level approvals. Implementations of this EIP must obey this principle.&lt;&#x2F;p&gt;
&lt;p&gt;Since this EIP is ERC-721 compatible, any wallets and smart contracts that can hold and manipulate standard ERC-721 tokens will have no risks of asset loss for ERC-3525 tokens due to incompatible standards implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Flash Loans</title>
        <published>2020-11-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Alberto Cuesta Cañada</name><uri>https://github.com/alcueca</uri>
	</author>
	
	<author>
		<name>Fiona Kobayashi</name><uri>https://github.com/fifikobayashi</uri>
	</author>
	
	<author>
		<name>fubuloubu</name><uri>https://github.com/fubuloubu</uri>
	</author>
	
	<author>
		<name>Austin Williams</name><uri>https://github.com/onewayfunction</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3156/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-3156-flash-loans-review-discussion/5077" />
        

        <id>https://wg-eips.ritovision.com/3156/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:3156"
            label="ERC-3156" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3156/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC provides standard interfaces and processes for single-asset flash loans.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A flash loan is a smart contract transaction in which a lender smart contract lends assets to a borrower smart contract with the condition that the assets are returned, plus an optional fee, before the end of the transaction. This ERC specifies interfaces for lenders to accept flash loan requests, and for borrowers to take temporary control of the transaction within the lender execution. The process for the safe execution of flash loans is also specified.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Flash loans allow smart contracts to lend an amount of tokens without a requirement for collateral, with the condition that they must be returned within the same transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Early adopters of the flash loan pattern have produced different interfaces and different use patterns. The diversification is expected to intensify, and with it the technical debt required to integrate with diverse flash lending patterns.&lt;&#x2F;p&gt;
&lt;p&gt;Some of the high level differences in the approaches across the protocols include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Repayment approaches at the end of the transaction, where some pull the principal plus the fee from the loan receiver, and others where the loan receiver needs to manually return the principal and the fee to the lender.&lt;&#x2F;li&gt;
&lt;li&gt;Some lenders offer the ability to repay the loan using a token that is different to what was originally borrowed, which can reduce the overall complexity of the flash transaction and gas fees.&lt;&#x2F;li&gt;
&lt;li&gt;Some lenders offer a single entry point into the protocol regardless of whether you&#x27;re buying, selling, depositing or chaining them together as a flash loan, whereas other protocols offer discrete entry points.&lt;&#x2F;li&gt;
&lt;li&gt;Some lenders allow to flash mint any amount of their native token without charging a fee, effectively allowing flash loans bounded by computational constraints instead of asset ownership constraints.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;A flash lending feature integrates two smart contracts using a callback pattern. These are called the LENDER and the RECEIVER in this EIP.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lender-specification&quot;&gt;Lender Specification&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;lender&lt;&#x2F;code&gt; MUST implement the IERC3156FlashLender interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.7.0 || ^0.8.0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;.&#x2F;IERC3156FlashBorrower.sol&amp;quot;;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;interface IERC3156FlashLender {&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The amount of currency available to be lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` that can be borrowed.&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;    function maxFlashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view returns (uint256);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The fee to be charged for a given loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` to be charged for the loan, on top of the returned principal.&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;    function flashFee(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view returns (uint256);&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Initiate a flash loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param data Arbitrary data structure, intended to contain user-defined parameters.&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;    function flashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC3156FlashBorrower receiver,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external returns (bool);&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 &lt;code&gt;maxFlashLoan&lt;&#x2F;code&gt; function MUST return the maximum loan possible for &lt;code&gt;token&lt;&#x2F;code&gt;. If a &lt;code&gt;token&lt;&#x2F;code&gt; is not currently supported &lt;code&gt;maxFlashLoan&lt;&#x2F;code&gt; MUST return 0, instead of reverting.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;flashFee&lt;&#x2F;code&gt; function MUST return the fee charged for a loan of &lt;code&gt;amount&lt;&#x2F;code&gt; &lt;code&gt;token&lt;&#x2F;code&gt;. If the token is not supported &lt;code&gt;flashFee&lt;&#x2F;code&gt; MUST revert.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST include a callback to the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; function in a &lt;code&gt;IERC3156FlashBorrower&lt;&#x2F;code&gt; contract.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function flashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    IERC3156FlashBorrower receiver,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) external returns (bool) {&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(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      receiver.onFlashLoan(msg.sender, token, amount, fee, data) == keccak256(&amp;quot;ERC3156FlashBorrower.onFlashLoan&amp;quot;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;quot;IERC3156: Callback failed&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;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 &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST transfer &lt;code&gt;amount&lt;&#x2F;code&gt; of &lt;code&gt;token&lt;&#x2F;code&gt; to &lt;code&gt;receiver&lt;&#x2F;code&gt; before the callback to the receiver.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST include &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as the &lt;code&gt;initiator&lt;&#x2F;code&gt; to &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST NOT modify the &lt;code&gt;token&lt;&#x2F;code&gt;, &lt;code&gt;amount&lt;&#x2F;code&gt; and &lt;code&gt;data&lt;&#x2F;code&gt; parameter received, and MUST pass them on to &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST include a &lt;code&gt;fee&lt;&#x2F;code&gt; argument to &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; with the fee to pay for the loan on top of the principal, ensuring that &lt;code&gt;fee == flashFee(token, amount)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;lender&lt;&#x2F;code&gt; MUST verify that the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; callback returns the keccak256 hash of &quot;ERC3156FlashBorrower.onFlashLoan&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;After the callback, the &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function MUST take the &lt;code&gt;amount + fee&lt;&#x2F;code&gt; &lt;code&gt;token&lt;&#x2F;code&gt; from the &lt;code&gt;receiver&lt;&#x2F;code&gt;, or revert if this is not successful.&lt;&#x2F;p&gt;
&lt;p&gt;If successful, &lt;code&gt;flashLoan&lt;&#x2F;code&gt; MUST return &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;receiver-specification&quot;&gt;Receiver Specification&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;receiver&lt;&#x2F;code&gt; of flash loans MUST implement the IERC3156FlashBorrower interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.7.0 || ^0.8.0;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;interface IERC3156FlashBorrower {&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Receive a flash loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param initiator The initiator of the loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param fee The additional amount of tokens to repay.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param data Arbitrary data structure, intended to contain user-defined parameters.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The keccak256 hash of &amp;quot;ERC3156FlashBorrower.onFlashLoan&amp;quot;&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;    function onFlashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address initiator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 fee,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external returns (bytes32);&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;For the transaction to not revert, &lt;code&gt;receiver&lt;&#x2F;code&gt; MUST approve &lt;code&gt;amount + fee&lt;&#x2F;code&gt; of &lt;code&gt;token&lt;&#x2F;code&gt; to be taken by &lt;code&gt;msg.sender&lt;&#x2F;code&gt; before the end of &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If successful, &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; MUST return the keccak256 hash of &quot;ERC3156FlashBorrower.onFlashLoan&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The interfaces described in this ERC have been chosen as to cover the known flash lending use cases, while allowing for safe and gas efficient implementations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;flashFee&lt;&#x2F;code&gt; reverts on unsupported tokens, because returning a numerical value would be incorrect.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;flashLoan&lt;&#x2F;code&gt; has been chosen as a function name as descriptive enough, unlikely to clash with other functions in the lender, and including both the use cases in which the tokens lent are held or minted by the lender.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;receiver&lt;&#x2F;code&gt; is taken as a parameter to allow flexibility on the implementation of separate loan initiators and receivers.&lt;&#x2F;p&gt;
&lt;p&gt;Existing flash lenders all provide flash loans of several token types from the same contract. Providing a &lt;code&gt;token&lt;&#x2F;code&gt; parameter in both the &lt;code&gt;flashLoan&lt;&#x2F;code&gt; and &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; functions matches closely the observed functionality.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;bytes calldata data&lt;&#x2F;code&gt; parameter is included for the caller to pass arbitrary information to the &lt;code&gt;receiver&lt;&#x2F;code&gt;, without impacting the utility of the &lt;code&gt;flashLoan&lt;&#x2F;code&gt; standard.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; has been chosen as a function name as descriptive enough, unlikely to clash with other functions in the &lt;code&gt;receiver&lt;&#x2F;code&gt;, and following the &lt;code&gt;onAction&lt;&#x2F;code&gt; naming pattern used as well in EIP-667.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;initiator&lt;&#x2F;code&gt; will often be required in the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; function, which the lender knows as &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. An alternative implementation which would embed the &lt;code&gt;initiator&lt;&#x2F;code&gt; in the &lt;code&gt;data&lt;&#x2F;code&gt; parameter by the caller would require an additional mechanism for the receiver to verify its accuracy, and is not advisable.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;amount&lt;&#x2F;code&gt; will be required in the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; function, which the lender took as a parameter. An alternative implementation which would embed the &lt;code&gt;amount&lt;&#x2F;code&gt; in the &lt;code&gt;data&lt;&#x2F;code&gt; parameter by the caller would require an additional mechanism for the receiver to verify its accuracy, and is not advisable.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;fee&lt;&#x2F;code&gt; will often be calculated in the &lt;code&gt;flashLoan&lt;&#x2F;code&gt; function, which the &lt;code&gt;receiver&lt;&#x2F;code&gt; must be aware of for repayment. Passing the &lt;code&gt;fee&lt;&#x2F;code&gt; as a parameter instead of appended to &lt;code&gt;data&lt;&#x2F;code&gt; is simple and effective.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;amount + fee&lt;&#x2F;code&gt; are pulled from the &lt;code&gt;receiver&lt;&#x2F;code&gt; to allow the &lt;code&gt;lender&lt;&#x2F;code&gt; to implement other features that depend on using &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, without having to lock them for the duration of a flash loan. An alternative implementation where the repayment is transferred to the &lt;code&gt;lender&lt;&#x2F;code&gt; is also possible, but would need all other features in the lender to be also based in using &lt;code&gt;transfer&lt;&#x2F;code&gt; instead of &lt;code&gt;transferFrom&lt;&#x2F;code&gt;. Given the lower complexity and prevalence of a &quot;pull&quot; architecture over a &quot;push&quot; architecture, &quot;pull&quot; was chosen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;No backwards compatibility issues identified.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;flash-borrower-reference-implementation&quot;&gt;Flash Borrower Reference Implementation&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.8.0;&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;import &amp;quot;.&#x2F;interfaces&#x2F;IERC20.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;.&#x2F;interfaces&#x2F;IERC3156FlashBorrower.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;.&#x2F;interfaces&#x2F;IERC3156FlashLender.sol&amp;quot;;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract FlashBorrower is IERC3156FlashBorrower {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    enum Action {NORMAL, OTHER}&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;    IERC3156FlashLender lender;&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;    constructor (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC3156FlashLender lender_&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;        lender = lender_;&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&gt;    &#x2F;&#x2F;&#x2F; @dev ERC-3156 Flash loan callback&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function onFlashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address initiator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 fee,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external override returns(bytes32) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            msg.sender == address(lender),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashBorrower: Untrusted lender&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;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            initiator == address(this),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashBorrower: Untrusted loan initiator&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;        (Action action) = abi.decode(data, (Action));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (action == Action.NORMAL) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; do one thing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } else if (action == Action.OTHER) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; do another&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;        return keccak256(&amp;quot;ERC3156FlashBorrower.onFlashLoan&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F;&#x2F; @dev Initiate a flash loan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function flashBorrow(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) public {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes memory data = abi.encode(Action.NORMAL);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 _allowance = IERC20(token).allowance(address(this), address(lender));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 _fee = lender.flashFee(token, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 _repayment = amount + _fee;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC20(token).approve(address(lender), _allowance + _repayment);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lender.flashLoan(this, token, amount, data);&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;h3 id=&quot;flash-mint-reference-implementation&quot;&gt;Flash Mint Reference Implementation&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.8.0;&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;import &amp;quot;..&#x2F;ERC20.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;..&#x2F;interfaces&#x2F;IERC20.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;..&#x2F;interfaces&#x2F;IERC3156FlashBorrower.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;..&#x2F;interfaces&#x2F;IERC3156FlashLender.sol&amp;quot;;&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;&#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; * @author Alberto Cuesta Cañada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; * @dev Extension of {ERC20} that allows flash minting.&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;contract FlashMinter is ERC20, IERC3156FlashLender {&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;    bytes32 public constant CALLBACK_SUCCESS = keccak256(&amp;quot;ERC3156FlashBorrower.onFlashLoan&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 public fee; &#x2F;&#x2F;  1 == 0.01 %.&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param fee_ The percentage of the loan `amount` that needs to be repaid, in addition to `amount`.&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;    constructor (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string memory name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string memory symbol,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 fee_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) ERC20(name, symbol) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fee = fee_;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The amount of currency available to be lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` that can be borrowed.&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;    function maxFlashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view override returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return type(uint256).max - totalSupply();&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The fee to be charged for a given loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency. Must match the address of this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` to be charged for the loan, on top of the returned principal.&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;    function flashFee(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view override returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            token == address(this),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashMinter: Unsupported currency&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;        return _flashFee(token, amount);&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Loan `amount` tokens to `receiver`, and takes it back plus a `flashFee` after the ERC3156 callback.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param receiver The contract receiving the tokens, needs to implement the `onFlashLoan(address user, uint256 amount, uint256 fee, bytes calldata)` interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency. Must match the address of this contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param data A data parameter to be passed on to the `receiver` for any custom use.&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;    function flashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC3156FlashBorrower receiver,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external override returns (bool){&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            token == address(this),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashMinter: Unsupported currency&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;        uint256 fee = _flashFee(token, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _mint(address(receiver), amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            receiver.onFlashLoan(msg.sender, token, amount, fee, data) == CALLBACK_SUCCESS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashMinter: Callback failed&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;        uint256 _allowance = allowance(address(receiver), address(this));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _allowance &amp;gt;= (amount + fee),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashMinter: Repay not approved&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;        _approve(address(receiver), address(this), _allowance - (amount + fee));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _burn(address(receiver), amount + fee);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return true;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The fee to be charged for a given loan. Internal function with no checks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` to be charged for the loan, on top of the returned principal.&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;    function _flashFee(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) internal view returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return amount * fee &#x2F; 10000;&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;h3 id=&quot;flash-loan-reference-implementation&quot;&gt;Flash Loan Reference Implementation&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.8.0;&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;import &amp;quot;..&#x2F;interfaces&#x2F;IERC20.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;..&#x2F;interfaces&#x2F;IERC3156FlashBorrower.sol&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import &amp;quot;..&#x2F;interfaces&#x2F;IERC3156FlashLender.sol&amp;quot;;&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;&#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; * @author Alberto Cuesta Cañada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; * @dev Extension of {ERC20} that allows flash lending.&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;contract FlashLender is IERC3156FlashLender {&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;    bytes32 public constant CALLBACK_SUCCESS = keccak256(&amp;quot;ERC3156FlashBorrower.onFlashLoan&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mapping(address =&amp;gt; bool) public supportedTokens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 public fee; &#x2F;&#x2F;  1 == 0.01 %.&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;&#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;     * @param supportedTokens_ Token contracts supported for flash lending.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param fee_ The percentage of the loan `amount` that needs to be repaid, in addition to `amount`.&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;    constructor(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address[] memory supportedTokens_,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 fee_&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;        for (uint256 i = 0; i &amp;lt; supportedTokens_.length; i++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            supportedTokens[supportedTokens_[i]] = true;&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;        fee = fee_;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Loan `amount` tokens to `receiver`, and takes it back plus a `flashFee` after the callback.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param receiver The contract receiving the tokens, needs to implement the `onFlashLoan(address user, uint256 amount, uint256 fee, bytes calldata)` interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param data A data parameter to be passed on to the `receiver` for any custom use.&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;    function flashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        IERC3156FlashBorrower receiver,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes calldata data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external override returns(bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            supportedTokens[token],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashLender: Unsupported currency&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;        uint256 fee = _flashFee(token, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IERC20(token).transfer(address(receiver), amount),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashLender: Transfer failed&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;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            receiver.onFlashLoan(msg.sender, token, amount, fee, data) == CALLBACK_SUCCESS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashLender: Callback failed&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;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IERC20(token).transferFrom(address(receiver), address(this), amount + fee),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashLender: Repay failed&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;        return true;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The fee to be charged for a given loan.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` to be charged for the loan, on top of the returned principal.&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;    function flashFee(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view override returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            supportedTokens[token],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;FlashLender: Unsupported currency&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;        return _flashFee(token, amount);&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The fee to be charged for a given loan. Internal function with no checks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param amount The amount of tokens lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` to be charged for the loan, on top of the returned principal.&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;    function _flashFee(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) internal view returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return amount * fee &#x2F; 10000;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev The amount of currency available to be lent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param token The loan currency.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The amount of `token` that can be borrowed.&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;    function maxFlashLoan(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) external view override returns (uint256) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return supportedTokens[token] ? IERC20(token).balanceOf(address(this)) : 0;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;verification-of-callback-arguments&quot;&gt;Verification of callback arguments&lt;&#x2F;h3&gt;
&lt;p&gt;The arguments of &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; are expected to reflect the conditions of the flash loan, but cannot be trusted unconditionally. They can be divided in two groups, that require different checks before they can be trusted to be genuine.&lt;&#x2F;p&gt;
&lt;ol start=&quot;0&quot;&gt;
&lt;li&gt;No arguments can be assumed to be genuine without some kind of verification. &lt;code&gt;initiator&lt;&#x2F;code&gt;, &lt;code&gt;token&lt;&#x2F;code&gt; and &lt;code&gt;amount&lt;&#x2F;code&gt; refer to a past transaction that might not have happened if the caller of &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; decides to lie. &lt;code&gt;fee&lt;&#x2F;code&gt; might be false or calculated incorrectly. &lt;code&gt;data&lt;&#x2F;code&gt; might have been manipulated by the caller.&lt;&#x2F;li&gt;
&lt;li&gt;To trust that the value of &lt;code&gt;initiator&lt;&#x2F;code&gt;, &lt;code&gt;token&lt;&#x2F;code&gt;, &lt;code&gt;amount&lt;&#x2F;code&gt; and &lt;code&gt;fee&lt;&#x2F;code&gt; are genuine a reasonable pattern is to verify that the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; caller is in a whitelist of verified flash lenders. Since often the caller of &lt;code&gt;flashLoan&lt;&#x2F;code&gt; will also be receiving the &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; callback this will be trivial. In all other cases flash lenders will need to be approved if the arguments in &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; are to be trusted.&lt;&#x2F;li&gt;
&lt;li&gt;To trust that the value of &lt;code&gt;data&lt;&#x2F;code&gt; is genuine, in addition to the check in point 1, it is recommended to verify that the &lt;code&gt;initiator&lt;&#x2F;code&gt; belongs to a group of trusted addresses. Trusting the &lt;code&gt;lender&lt;&#x2F;code&gt; and the &lt;code&gt;initiator&lt;&#x2F;code&gt; is enough to trust that the contents of &lt;code&gt;data&lt;&#x2F;code&gt; are genuine.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;flash-lending-security-considerations&quot;&gt;Flash lending security considerations&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;automatic-approvals&quot;&gt;Automatic approvals&lt;&#x2F;h4&gt;
&lt;p&gt;The safest approach is to implement an approval for &lt;code&gt;amount+fee&lt;&#x2F;code&gt; before the &lt;code&gt;flashLoan&lt;&#x2F;code&gt; is executed.&lt;&#x2F;p&gt;
&lt;p&gt;Any &lt;code&gt;receiver&lt;&#x2F;code&gt; that keeps an approval for a given &lt;code&gt;lender&lt;&#x2F;code&gt; needs to include in &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; a mechanism to verify that the initiator is trusted.&lt;&#x2F;p&gt;
&lt;p&gt;Any &lt;code&gt;receiver&lt;&#x2F;code&gt; that includes in &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; the approval for the &lt;code&gt;lender&lt;&#x2F;code&gt; to take the &lt;code&gt;amount + fee&lt;&#x2F;code&gt; needs to be combined with a mechanism to verify that the initiator is trusted.&lt;&#x2F;p&gt;
&lt;p&gt;If an unsuspecting contract with a non-reverting fallback function, or an EOA, would approve a &lt;code&gt;lender&lt;&#x2F;code&gt; implementing ERC3156, and not immediately use the approval, and if the &lt;code&gt;lender&lt;&#x2F;code&gt; would not verify the return value of &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt;, then the unsuspecting contract or EOA could be drained of funds up to their allowance or balance limit. This would be executed by an &lt;code&gt;initiator&lt;&#x2F;code&gt; calling &lt;code&gt;flashLoan&lt;&#x2F;code&gt; on the victim. The flash loan would be executed and repaid, plus any fees, which would be accumulated by the &lt;code&gt;lender&lt;&#x2F;code&gt;. For this reason, it is important that the &lt;code&gt;lender&lt;&#x2F;code&gt; implements the specification in full and reverts if &lt;code&gt;onFlashLoan&lt;&#x2F;code&gt; doesn&#x27;t return the keccak256 hash for &quot;ERC3156FlashBorrower.onFlashLoan&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flash-minting-external-security-considerations&quot;&gt;Flash minting external security considerations&lt;&#x2F;h3&gt;
&lt;p&gt;The typical quantum of tokens involved in flash mint transactions will give rise to new innovative attack vectors.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-1-interest-rate-attack&quot;&gt;Example 1 - interest rate attack&lt;&#x2F;h4&gt;
&lt;p&gt;If there exists a lending protocol that offers stable interests rates, but it does not have floor&#x2F;ceiling rate limits and it does not rebalance the fixed rate based on flash-induced liquidity changes, then it could be susceptible to the following scenario:&lt;&#x2F;p&gt;
&lt;p&gt;FreeLoanAttack.sol&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Flash mint 1 quintillion STAB&lt;&#x2F;li&gt;
&lt;li&gt;Deposit the 1 quintillion STAB + $1.5 million worth of ETH collateral&lt;&#x2F;li&gt;
&lt;li&gt;The quantum of your total deposit now pushes the stable interest rate down to 0.00001% stable interest rate&lt;&#x2F;li&gt;
&lt;li&gt;Borrow 1 million STAB on 0.00001% stable interest rate based on the 1.5M ETH collateral&lt;&#x2F;li&gt;
&lt;li&gt;Withdraw and burn the 1 quint STAB to close the original flash mint&lt;&#x2F;li&gt;
&lt;li&gt;You now have a 1 million STAB loan that is practically interest free for perpetuity ($0.10 &#x2F; year in interest)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The key takeaway being the obvious need to implement a flat floor&#x2F;ceiling rate limit and to rebalance the rate based on short term liquidity changes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-2-arithmetic-overflow-and-underflow&quot;&gt;Example 2 - arithmetic overflow and underflow&lt;&#x2F;h4&gt;
&lt;p&gt;If the flash mint provider does not place any limits on the amount of flash mintable tokens in a transaction, then anyone can flash mint 2^256-1 amount of tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The protocols on the receiving end of the flash mints will need to ensure their contracts can handle this, either by using a compiler that embeds overflow protection in the smart contract bytecode, or by setting explicit checks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flash-minting-internal-security-considerations&quot;&gt;Flash minting internal security considerations&lt;&#x2F;h3&gt;
&lt;p&gt;The coupling of flash minting with business specific features in the same platform can easily lead to unintended consequences.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-treasury-draining&quot;&gt;Example - Treasury draining&lt;&#x2F;h4&gt;
&lt;p&gt;Assume a smart contract that flash lends its native token. The same smart contract borrows from a third party when users burn the native token. This pattern would be used to aggregate in the smart contract the collateralized debt of several users into a single account in the third party. The flash mint could be used to cause the lender to borrow to its limit, and then pushing interest rates in the underlying lender, liquidate the flash lender:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Flash mint from &lt;code&gt;lender&lt;&#x2F;code&gt; a very large amount of FOO.&lt;&#x2F;li&gt;
&lt;li&gt;Redeem FOO for BAR, causing &lt;code&gt;lender&lt;&#x2F;code&gt; to borrow from &lt;code&gt;underwriter&lt;&#x2F;code&gt; all the way to its borrowing limit.&lt;&#x2F;li&gt;
&lt;li&gt;Trigger a debt rate increase in &lt;code&gt;underwriter&lt;&#x2F;code&gt;, making &lt;code&gt;lender&lt;&#x2F;code&gt; undercollateralized.&lt;&#x2F;li&gt;
&lt;li&gt;Liquidate the &lt;code&gt;lender&lt;&#x2F;code&gt; for profit.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>NFT Royalty Standard</title>
        <published>2020-09-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Zach Burks</name><uri>https://github.com/vexycats</uri>
	</author>
	
	<author>
		<name>James Morgan</name><uri>https://github.com/jamesmorgan</uri>
	</author>
	
	<author>
		<name>Blaine Malone</name><uri>https://github.com/blmalone</uri>
	</author>
	
	<author>
		<name>James Seibel</name><uri>https://github.com/seibelj</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2981/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2907" />
        

        <id>https://wg-eips.ritovision.com/2981/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2981"
            label="ERC-2981" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2981/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal support for royalty payments across all NFT marketplaces and ecosystem participants.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard allows contracts, such as NFTs that support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; interfaces, to signal a royalty amount to be paid to the NFT creator or rights holder every time the NFT is sold or re-sold. This is intended for NFT marketplaces that want to support the ongoing funding of artists and other NFT creators. The royalty payment must be voluntary, as transfer mechanisms such as &lt;code&gt;transferFrom()&lt;&#x2F;code&gt; include NFT transfers between wallets, and executing them does not always imply a sale occurred. Marketplaces and individuals implement this standard by retrieving the royalty payment information with &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt;, which specifies how much to pay to which address for a given sale price. The exact mechanism for paying and notifying the recipient will be defined in future EIPs. This ERC should be considered a minimal, gas-efficient building block for further innovation in NFT royalty payments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There are many marketplaces for NFTs with multiple unique royalty payment implementations that are not easily compatible or usable by other marketplaces. Just like the early days of ERC-20 tokens, NFT marketplace smart contracts are varied by ecosystem and not standardized. This EIP enables all marketplaces to retrieve royalty payment information for a given NFT. This enables accurate royalty payments regardless of which marketplace the NFT is sold or re-sold at.&lt;&#x2F;p&gt;
&lt;p&gt;Many of the largest NFT marketplaces have implemented bespoke royalty payment solutions that are incompatible with other marketplaces. This standard implements standardized royalty information retrieval that can be accepted across any type of NFT marketplace. This minimalist proposal only provides a mechanism to fetch the royalty amount and recipient. The actual funds transfer is something which the marketplace should execute.&lt;&#x2F;p&gt;
&lt;p&gt;This standard allows NFTs that support &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; interfaces, to have a standardized way of signalling royalty information. More specifically, these contracts can now calculate a royalty amount to provide to the rightful recipient.&lt;&#x2F;p&gt;
&lt;p&gt;Royalty amounts are always a percentage of the sale price. If a marketplace chooses &lt;em&gt;not&lt;&#x2F;em&gt; to implement this EIP, then no funds will be paid for secondary sales. It is believed that the NFT marketplace ecosystem will voluntarily implement this royalty payment standard; in a bid to provide ongoing funding for artists&#x2F;creators. NFT buyers will assess the royalty payment as a factor when making NFT purchasing decisions.&lt;&#x2F;p&gt;
&lt;p&gt;Without an agreed royalty payment standard, the NFT ecosystem will lack an effective means to collect royalties across all marketplaces and artists and other creators will not receive ongoing funding. This will hamper the growth and adoption of NFTs and demotivate NFT creators from minting new and innovative tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Enabling all NFT marketplaces to unify on a single royalty payment standard will benefit the entire NFT ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;While this standard focuses on NFTs and compatibility with the ERC-721 and ERC-1155 standards, EIP-2981 does not require compatibility with ERC-721 and ERC-1155 standards. Any other contract could integrate with EIP-2981 to return royalty payment information. ERC-2981 is, therefore, a universal royalty standard for many asset types.&lt;&#x2F;p&gt;
&lt;p&gt;At a glance, here&#x27;s an example conversation summarizing NFT royalty payments today:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Artist&lt;&#x2F;strong&gt;: &quot;Do you support royalty payments on your platform?&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Marketplace&lt;&#x2F;strong&gt;: &quot;Yes we have royalty payments, but if your NFT is sold on another marketplace then we cannot enforce this payment.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Artist&lt;&#x2F;strong&gt;: &quot;What about other marketplaces that support royalties, don&#x27;t you share my royalty information to make this work?&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Marketplace&lt;&#x2F;strong&gt;: &quot;No, we do not share royalty information.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL
NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and
&quot;OPTIONAL&quot; in this document are to be interpreted as described in
RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;ERC-721 and ERC-1155 compliant contracts MAY implement this ERC for royalties to provide a standard method of specifying royalty payment information.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Marketplaces that support this standard &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; implement some method of transferring royalties to the royalty recipient. Standards for the actual transfer and notification of funds will be specified in future EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;Marketplaces &lt;strong&gt;MUST&lt;&#x2F;strong&gt; pay the royalty in the same unit of exchange as that of the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; passed to &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt;. This is equivalent to saying that the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; parameter and the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; return value &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be denominated in the same monetary unit. For example, if the sale price is in ETH, then the royalty payment must also be paid in ETH, and if the sale price is in USDC, then the royalty payment must also be paid in USDC.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers of this standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; calculate a percentage of the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; when calculating the royalty amount. Subsequent invocations of &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; &lt;strong&gt;MAY&lt;&#x2F;strong&gt; return a different &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt;. Though there are some important considerations for implementers if they choose to perform different percentage calculations between &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; invocations.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; function is not aware of the unit of exchange for the sale and royalty payment. With that in mind, implementers &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; return a fixed&#x2F;constant &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt;, wherein they&#x27;re ignoring the &lt;code&gt;_salePrice&lt;&#x2F;code&gt;. For the same reason, implementers &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; determine the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; based on comparing the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; with constant numbers. In both cases, the &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; function makes assumptions on the unit of exchange, which &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be avoided.&lt;&#x2F;p&gt;
&lt;p&gt;The percentage value used must be independent of the sale price for reasons previously mentioned (i.e. if the percentage value 10%, then 10% &lt;strong&gt;MUST&lt;&#x2F;strong&gt; apply whether &lt;code&gt;_salePrice&lt;&#x2F;code&gt; is 10, 10000 or 1234567890). If the royalty fee calculation results in a remainder, implementers &lt;strong&gt;MAY&lt;&#x2F;strong&gt; round up or round down to the nearest integer. For example, if the royalty fee is 10% and &lt;code&gt;_salePrice&lt;&#x2F;code&gt; is 999, the implementer can return either 99 or 100 for &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt;, both are valid.&lt;&#x2F;p&gt;
&lt;p&gt;The implementer &lt;strong&gt;MAY&lt;&#x2F;strong&gt; choose to change the percentage value based on other predictable variables that do not make assumptions about the unit of exchange. For example, the percentage value may drop linearly over time. An approach like this &lt;strong&gt;SHOULD NOT&lt;&#x2F;strong&gt; be based on variables that are unpredictable like &lt;code&gt;block.timestamp&lt;&#x2F;code&gt;, but instead on other more predictable state changes. One more reasonable approach &lt;strong&gt;MAY&lt;&#x2F;strong&gt; use the number of transfers of an NFT to decide which percentage value is used to calculate the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt;. The idea being that the percentage value could decrease after each transfer of the NFT. Another example could be using a different percentage value for each unique &lt;code&gt;_tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Marketplaces that support this standard &lt;strong&gt;SHOULD NOT&lt;&#x2F;strong&gt; send a zero-value transaction if the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; returned is &lt;code&gt;0&lt;&#x2F;code&gt;. This would waste gas and serves no useful purpose in this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;Marketplaces that support this standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; pay royalties no matter where the sale occurred or in what currency, including on-chain sales, over-the-counter (OTC) sales and off-chain sales such as at auction houses. As royalty payments are voluntary, entities that respect this EIP must pay no matter where the sale occurred - a sale conducted outside of the blockchain is still a sale. The exact mechanism for paying and notifying the recipient will be defined in future EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers of this standard &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have all of the following functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.6.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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;IERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for the NFT Royalty Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC2981&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 bytes to add to interface array - set in parent contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; implementing this standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes4(keccak256(&amp;quot;royaltyInfo(uint256,uint256)&amp;quot;)) == 0x2a55205a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _registerInterface(_INTERFACE_ID_ERC2981);&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Called with the sale price to determine how much royalty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;          is owed and to whom.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the NFT asset queried for royalty information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _salePrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the sale price of the NFT asset specified by _tokenId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - address of who should be sent the royalty payment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; royaltyAmount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; - the royalty payment amount for _salePrice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _salePrice&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; royaltyAmount&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if a contract implements an interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface identifier, as specified in ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface identification is specified in ERC-165. This function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  uses less than 30,000 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if the contract implements `interfaceID` and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `interfaceID` is not 0xffffffff, `false` otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h3&gt;
&lt;p&gt;This standard being used on an ERC-721 during deployment:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;deploying-an-erc-721-and-signaling-support-for-erc-2981&quot;&gt;Deploying an ERC-721 and signaling support for ERC-2981&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;constructor&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; baseURI&lt;&#x2F;span&gt;&lt;span&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&gt;        _name &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&gt;        _symbol &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _setBaseURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;baseURI&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; register the supported interfaces to conform to ERC721 via ERC165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _registerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_INTERFACE_ID_ERC721&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _registerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_INTERFACE_ID_ERC721_METADATA&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _registerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_INTERFACE_ID_ERC721_ENUMERABLE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Royalties interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _registerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_INTERFACE_ID_ERC2981&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;checking-if-the-nft-being-sold-on-your-marketplace-implemented-royalties&quot;&gt;Checking if the NFT being sold on your marketplace implemented royalties&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; _INTERFACE_ID_ERC2981 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkRoyalties&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_INTERFACE_ID_ERC2981&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;optional-royalty-payments&quot;&gt;Optional royalty payments&lt;&#x2F;h3&gt;
&lt;p&gt;It is impossible to know which NFT transfers are the result of sales, and which are merely wallets moving or consolidating their NFTs. Therefore, we cannot force every transfer function, such as &lt;code&gt;transferFrom()&lt;&#x2F;code&gt; in ERC-721, to involve a royalty payment as not every transfer is a sale that would require such payment. We believe the NFT marketplace ecosystem will voluntarily implement this royalty payment standard to provide ongoing funding for artists&#x2F;creators. NFT buyers will assess the royalty payment as a factor when making NFT purchasing decisions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;simple-royalty-payments-to-a-single-address&quot;&gt;Simple royalty payments to a single address&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP does not specify the manner of payment to the royalty recipient. Furthermore, it is impossible to fully know and efficiently implement all possible types of royalty payments logic. With that said, it is on the royalty payment receiver to implement all additional complexity and logic for fee splitting, multiple receivers, taxes, accounting, etc. in their own receiving contract or off-chain processes. Attempting to do this as part of this standard, it would dramatically increase the implementation complexity, increase gas costs, and could not possibly cover every potential use-case. This ERC should be considered a minimal, gas-efficient building block for further innovation in NFT royalty payments. Future EIPs can specify more details regarding payment transfer and notification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;royalty-payment-percentage-calculation&quot;&gt;Royalty payment percentage calculation&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP mandates a percentage-based royalty fee model. It is likely that the most common case of percentage calculation will be where the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; is always calculated from the &lt;code&gt;_salePrice&lt;&#x2F;code&gt; using a fixed percent i.e. if the royalty fee is 10%, then a 10% royalty fee must apply whether &lt;code&gt;_salePrice&lt;&#x2F;code&gt; is 10, 10000 or 1234567890.&lt;&#x2F;p&gt;
&lt;p&gt;As previously mentioned, implementers can get creative with this percentage-based calculation but there are some important caveats to consider. Mainly, ensuring that the &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; function is not aware of the unit of exchange and that unpredictable variables are avoided in the percentage calculation. To follow up on the earlier &lt;code&gt;block.timestamp&lt;&#x2F;code&gt; example, there is some nuance which can be highlighted if the following events ensued:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Marketplace sells NFT.&lt;&#x2F;li&gt;
&lt;li&gt;Marketplace delays &lt;code&gt;X&lt;&#x2F;code&gt; days before invoking &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; and sending payment.&lt;&#x2F;li&gt;
&lt;li&gt;Marketplace receives &lt;code&gt;Y&lt;&#x2F;code&gt; for &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; which was significantly different from the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; amount that would&#x27;ve been calculated &lt;code&gt;X&lt;&#x2F;code&gt; days prior if no delay had occurred.&lt;&#x2F;li&gt;
&lt;li&gt;Royalty recipient is dissatisfied with the delay from the marketplace and for this reason, they raise a dispute.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Rather than returning a percentage and letting the marketplace calculate the royalty amount based on the sale price, a &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; value is returned so there is no dispute with a marketplace over how much is owed for a given sale price. The royalty fee payer must pay the &lt;code&gt;royaltyAmount&lt;&#x2F;code&gt; that &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; stipulates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unit-less-royalty-payment-across-all-marketplaces-both-on-chain-and-off-chain&quot;&gt;Unit-less royalty payment across all marketplaces, both on-chain and off-chain&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP does not specify a currency or token used for sales and royalty payments. The same percentage-based royalty fee must be paid regardless of what currency, or token was used in the sale, paid in the same currency or token. This applies to sales in any location including on-chain sales, over-the-counter (OTC) sales, and off-chain sales using fiat currency such as at auction houses. As royalty payments are voluntary, entities that respect this EIP must pay no matter where the sale occurred - a sale outside of the blockchain is still a sale. The exact mechanism for paying and notifying the recipient will be defined in future EIPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;universal-royalty-payments&quot;&gt;Universal Royalty Payments&lt;&#x2F;h3&gt;
&lt;p&gt;Although designed specifically with NFTs in mind, this standard does not require that a contract implementing EIP-2981 is compatible with either ERC-721 or ERC-1155 standards. Any other contract could use this interface to return royalty payment information, provided that it is able to uniquely identify assets within the constraints of the interface. ERC-2981 is, therefore, a universal royalty standard for many other asset types.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is compatible with current ERC-721 and ERC-1155 standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Serenity Phase 0</title>
        <published>2020-09-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Danny Ryan</name><uri>https://github.com/djrtwo</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2982/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/serenity-phase-0-eip/4621" />
        

        <id>https://wg-eips.ritovision.com/2982/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        

        
        <category
            term="tag:eip:2982"
            label="EIP-2982" />
        

        
        

        
        <summary type="html">Phase 0 of the release schedule of Serenity, a series of updates to Ethereum a scalable, proof-of-stake consensus</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2982/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP specifies Phase 0 of Serenity (eth2), a multi-phased upgrade to the consensus mechanism for Ethereum mainnet. In Phase 0, the existing PoW chain and mechanics are entirely unaffected, while a PoS chain -- the beacon chain -- is built in parallel to serve as the core of the upgraded consensus. In subsequent phases, the beacon chain is enhanced to support and secure the consensus of a number of parallel shard chains, ultimately incorporating current Ethereum mainnet as one of those shards.&lt;&#x2F;p&gt;
&lt;p&gt;At the core of the beacon chain is a proof of stake consensus mechanism called Casper the Friendly Finality Gadget (FFG) and a fork-choice rule called Latest Message Driven Greedy Heaviest Observed Sub-Tree (LMD-GHOST). Phase 0 is centered primarily around the mechanics and incentives of validators executing these algorithms. The detailed specifications for eth2 are contained in an independent repository from this EIP, and safety and liveness proofs can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;arxiv-2003.03052-Combining-GHOST-and-Casper.pdf&quot;&gt;Combining GHOST and Casper&lt;&#x2F;a&gt; paper. To avoid duplication, this EIP just references relevant spec files and releases.&lt;&#x2F;p&gt;
&lt;p&gt;Early phases of eth2 are executed without any breaking consensus changes on current Ethereum mainnet. This EIP serves to document the bootstrapping of this consensus mechanism and note the path for eth2 to supplant Ethereum&#x27;s current proof-of-work (PoW) consensus.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Eth2 aims to fulfill the original vision of Ethereum to support an efficient, global-scale, general-purpose transactional platform while retaining high cryptoeconomic security and decentralization.&lt;&#x2F;p&gt;
&lt;p&gt;Today, Ethereum blocks are consistently full due to increasingly high demand for decentralized applications. Ever since the first serious spikes in adoption in 2017 (cryptokitties), the Ethereum community has consistently and vocally demanded scaling solutions.&lt;&#x2F;p&gt;
&lt;p&gt;Since day 0 of Ethereum, the investigation and expectation in scaling solutions has been two-pronged -- scale from both Layer 1 upgrades and Layer 2 adoption. This EIP represents the start to a multi-phased rollout of the former.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scaling-through-sharding&quot;&gt;Scaling through sharding&lt;&#x2F;h3&gt;
&lt;p&gt;As the Ethereum network and the applications built upon it have seen increasing usage over the past 5 years, blocks have become regularly full and the gas price market continues to climb. Simple increases to the block gas-limit of the current Ethereum chain are unable to account for the increase in demand of the system without inducing an unsustainably high resource burden (in the form of bandwidth, computational, and disk resources) on consumer nodes. To retain decentralization while scaling up the Ethereum network, another path must be taken.&lt;&#x2F;p&gt;
&lt;p&gt;To provide more scale to Ethereum, while not inducing a restrictively high burden on both consumer and consensus nodes, eth2 introduces a &quot;sharded&quot; solution in which a number of blockchain shards -- each of similar capacity to Ethereum mainnet today -- run in parallel under a unified consensus mechanism. The core consensus (the beacon chain) and a small number of these shards can be processed via a single consumer machine, while the aggregate of the system provides much higher capacity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;decentralization-and-economic-finality-through-proof-of-stake&quot;&gt;Decentralization and economic finality through proof-of-stake&lt;&#x2F;h3&gt;
&lt;p&gt;Since the early days of Ethereum, proof-of-stake has been a long-awaited desideratum for the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Increased decentralization of the core consensus by lowering the barrier to entry and technical requirements of participation&lt;&#x2F;li&gt;
&lt;li&gt;Increased cryptoeconomic security via in-protocol penalties for misbehaviour and the addition of economic finality&lt;&#x2F;li&gt;
&lt;li&gt;Elimination of the energy hungry mining of the current PoW consensus mechanism&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In addition to the above, PoS has synergies with the sharding scaling solution. Due to the random sampling requirement of sharding, PoS provides a more simple and direct access to the &quot;active validator set&quot; than PoW and thus allows for a more direct sharded protocol construction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Phase 0 is designed to require &lt;em&gt;no breaking consensus changes&lt;&#x2F;em&gt; to existing Ethereum mainnet. Instead, this is the bootstrapping a new PoS consensus that can, once stable, supplant the current PoW consensus.&lt;&#x2F;p&gt;
&lt;p&gt;Phase 0 specifications are maintained in a repository independent of this EIP. &lt;code&gt;SPEC_RELEASE_VERSION&lt;&#x2F;code&gt; release of the specs at &lt;code&gt;SPEC_RELEASE_COMMIT&lt;&#x2F;code&gt; are considered the canonical Phase 0 specs for this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP provides a high level view on the Phase 0 mechanisms, especially those that are relevant to Ethereum mainnet (e.g. the deposit contract) and users (e.g. validator mechanics and eth2 issuance). The extended and low level details remain in the &lt;code&gt;consensus-specs&lt;&#x2F;code&gt; repository&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SPEC_RELEASE_VERSION&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;v1.0.0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SPEC_RELEASE_COMMIT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;579da6d2dc734b269dbf67aa1004b54bb9449784&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x00000000219ab540356cBB839Cbe05303d7705Fa&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_GENESIS_TIME&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1606824000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BASE_REWARD_FACTOR&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**6&lt;&#x2F;code&gt; (64)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;INACTIVITY_PENALTY_QUOTIENT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**26&lt;&#x2F;code&gt; (67,108,864)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;PROPORTIONAL_SLASHING_MULTIPLIER&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;MIN_SLASHING_PENALTY_QUOTIENT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;2**7&lt;&#x2F;code&gt; (128)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;&#x2F;em&gt; Eth2 has many more Phase 0 configuration parameters but the majority are left out of this EIP for brevity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;validator-deposit-contract&quot;&gt;Validator deposit contract&lt;&#x2F;h3&gt;
&lt;p&gt;In Phase 0, eth2 uses a contract deployed on Ethereum mainnet -- the Deposit Contract -- at &lt;code&gt;DEPOSIT_CONTRACT_ADDRESS&lt;&#x2F;code&gt; to onboard validators into the PoS consensus of the beacon chain.&lt;&#x2F;p&gt;
&lt;p&gt;To participate in the PoS consensus, users submit validator deposits to the deposit contract. The beacon chain comes to consensus on the state of this contract and processes new validator deposits. This uni-directional deposit mechanism is the only technical link between the two components of the system (Ethereum mainnet and beacon chain) in Phase 0.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;beacon-chain-and-validator-mechanics&quot;&gt;Beacon chain and validator mechanics&lt;&#x2F;h3&gt;
&lt;p&gt;Users who choose to participate in eth2 consensus deposit ETH collateral into the deposit contract in order to be inducted into the beacon chain validator set. From there, these validators are responsible for constructing the &lt;strong&gt;beacon chain&lt;&#x2F;strong&gt; (note that these consensus participants in PoS are akin to miners in PoW).&lt;&#x2F;p&gt;
&lt;p&gt;The beacon chain is a pure PoS chain that in Phase 0 is primarily concerned with maintaining its own consensus and managing the registry of validators. The consensus rules define &lt;em&gt;roles&lt;&#x2F;em&gt; (e.g. block proposal, block attesting) that validators are expected to participate in; validators who perform their roles well are rewarded, and validators who perform their roles poorly or are offline are penalized. Phase 0 does not yet include any ETH transfer, sharding or smart contract &#x2F; VM execution capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;In subsequent phases, additional mechanisms and validator responsibilities will be added to the beacon chain to manage the consensus of a number of parallel shard chains (&quot;Phase 1&quot;), to integrate the existing Ethereum system (&quot;Phase 1.5&quot;) and to add full support for sharded smart contract execution (&quot;Phase 2&quot;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;issuance&quot;&gt;Issuance&lt;&#x2F;h3&gt;
&lt;p&gt;To incentivize validators to deposit ether collateral and participate in the eth2 consensus, we propose that rewards (in the form of Ethereum&#x27;s native asset, ether) be regularly issued to consensus participants. Due to the beacon chain operating in parallel to the existing PoW chain in early phases of eth2, this issuance is &lt;em&gt;in addition to&lt;&#x2F;em&gt; any PoW rewards until the existing chain is merged into eth2 as a shard.&lt;&#x2F;p&gt;
&lt;p&gt;The amount of ether issued to validators on the beacon chain is proportional to the square root of the total ether deposited. This issuance curve was chosen as a more stable and sustainable curve to the two obvious alternatives -- fixed total issuance and fixed issuance per ether staked. For a more technical discussion on this choice see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;ef-Discouragement-Attacks.pdf&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In eth2, this curve is parameterized by &lt;code&gt;BASE_REWARD_FACTOR&lt;&#x2F;code&gt; in the context of slot time and epoch length. Below is the issuance curve as a function of ether staked, along with a table of examples for illustration. Note, all figures shown are annualized.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;2982-issuance.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Active Deposits&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Max Annual Validator Reward*&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Max Annual ETH Issued*&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0.5M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;23.50%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;117,527&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;16.60%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;166,208&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;11.75%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;235,052&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;8.31%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;332,411&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;5.88%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;470,104&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;16M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;4.16%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;664,801&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;32M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2.94%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;940,167&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;64M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2.08%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1,329,603&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;128M ETH&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1.47%&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1,880,334&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;em&gt;*Assuming validators are online 100% of the time and behaving optimally. Suboptimal validator behavior will lead to reduced rewards and&#x2F;or penalties that reduce total issuance.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initial-punitive-parameters&quot;&gt;Initial punitive parameters&lt;&#x2F;h3&gt;
&lt;p&gt;For PoS protocols to be crypto-economically secure, in-protocol penalties are required. Small offline penalties incentivize validator liveness, whereas (potentially) much larger penalties provide protocol security in the event of tail-risk scenarios.&lt;&#x2F;p&gt;
&lt;p&gt;Specifically, the following significant penalties exist:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Inactivity Leak&lt;&#x2F;strong&gt;: an offline penalty that increases each epoch is applied to validators during extended times of no finality (e.g. if one-third or more are offline or not on the canonical chain). This ensures the chain can eventually regain finality even under catastrophic conditions.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Slashing&lt;&#x2F;strong&gt;: a penalty applied to validators that sign &lt;em&gt;explicitly malicious&lt;&#x2F;em&gt; messages that could lead to the construction and finalization of two conflicting chains (e.g. two blocks or attestations in the same slot). This penalty is designed to scale up in proportion to the number of slashable validators in the same time period such that if a critical number (wrt chain safety) of slashings have occurred, validators are &lt;em&gt;maximally&lt;&#x2F;em&gt; punished.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For the initial launch of Phase 0, the parameters defining the magnitude of these penalties -- &lt;code&gt;INACTIVITY_PENALTY_QUOTIENT&lt;&#x2F;code&gt;, &lt;code&gt;PROPORTIONAL_SLASHING_MULTIPLIER&lt;&#x2F;code&gt;, and &lt;code&gt;MIN_SLASHING_PENALTY_QUOTIENT&lt;&#x2F;code&gt; -- have been tuned to be less punitive than their final intended values. This provides a more forgiving environment for early validators and client software in an effort to encourage validation in this early, higher technical-risk stage.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;INACTIVITY_PENALTY_QUOTIENT&lt;&#x2F;code&gt; is configured initially to four times its final value&lt;&#x2F;em&gt;. This results in a slower inactivity leak during times of non-finality, which means the chain is less responsive to such an event. If there is an extended time of non-finality during the early months of eth2, it is far more likely to be due to technical issues with client software rather than some sort of global catastrophic event.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;PROPORTIONAL_SLASHING_MULTIPLIER&lt;&#x2F;code&gt; is configured initially to one-third of its final value&lt;&#x2F;em&gt;. This results in a lower accountable safety margin in the event of an attack. If any validators are slashed in the early months of eth2, it is far more likely to be the result of user mismanagement of keys and&#x2F;or issues with client software than an organized attack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;MIN_SLASHING_PENALTY_QUOTIENT&lt;&#x2F;code&gt; configured initially to four times its final value&lt;&#x2F;em&gt;. This results in a lower guaranteed minimum penalty for a slashable offense and thus reduces the baseline punitive incentive to keep an individual validator&#x27;s system secure. As with &lt;code&gt;PROPORTIONAL_SLASHING_MULTIPLIER&lt;&#x2F;code&gt;, slashings during the early months of eth2 are far more likely to be due to user mismanagement, or issues with client software, than an organized attack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;principles&quot;&gt;Principles&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simplicity&lt;&#x2F;strong&gt;: especially since cryptoeconomic proof of stake and quadratic sharding are inherently complex, the protocol should strive for maximum simplicity in its decisions as much as possible. This is important because it (i) minimizes development costs, (ii) reduces risk of unforeseen security issues, and (iii) allows protocol designers to more easily convince users that parameter choices are legitimate. When complexity is unavoidable to achieve a given level of functionality, the preference order for where the complexity goes is: layer 2 protocols &amp;gt; client implementations &amp;gt; protocol spec.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Long-term stability&lt;&#x2F;strong&gt;: the low levels of the protocol should ideally be built so that there is no need to change them for a decade or longer, and any needed innovation can happen on higher levels (client implementations or layer 2 protocols).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Sufficiency&lt;&#x2F;strong&gt;: it should be fundamentally possible to build as many classes of applications as possible on top of the protocol.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Defense in depth&lt;&#x2F;strong&gt;: the protocol should continue to work as well as possible under a variety of possible security assumptions (eg. regarding network latency, fault count, the motivations of users)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Full light-client verifiability&lt;&#x2F;strong&gt;: given some assumptions (eg. network latency, bounds on attacker budget, 1-of-N or few-of-N honest minority), a client verifying a small fixed amount of data (ideally just the beacon chain) should be able to gain indirect assurance that all of the data in the full system is available and valid, even under a 51% attack (note: this is a form of defense-in-depth but it&#x27;s important enough to be separate)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-layer-1-vs-layer-2-tradeoff&quot;&gt;The Layer 1 vs Layer 2 Tradeoff&lt;&#x2F;h3&gt;
&lt;p&gt;The Ethereum roadmap uses a mixed layer 1 &#x2F; layer 2 approach. We focus on serving a particular type of layer 2 (rollups) because it&#x27;s the only kind of layer 2 that both inherits the security of layer 1 and provides scaling of general-purpose applications. However, rollups come at a cost: they require some on-chain data &lt;em&gt;per transaction&lt;&#x2F;em&gt;, and so a blockchain with really high capacity rollups must be able to handle a still quite high amount of data bandwidth. So make this more feasible, we are implementing on scalable data layer technologies, particularly data availability sampling.&lt;&#x2F;p&gt;
&lt;p&gt;The reason to not take a pure layer 2 approach is that pure layer 2 scaling can only be done either with trust-based solutions (not desirable), or with channels or plasma (which have inherent limitations and cannot support the full EVM.&lt;&#x2F;p&gt;
&lt;p&gt;The reason to not take a pure layer 1 approach is to enable more room for experimentation in execution layers, and allow the base protocol to be simpler and have less intensive governance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-proof-of-stake&quot;&gt;Why proof of stake&lt;&#x2F;h3&gt;
&lt;p&gt;In short:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No need to consume large quantities of electricity&lt;&#x2F;strong&gt; in order to secure a blockchain (e.g. it&#x27;s estimated that both Bitcoin and Ethereum burn over $1 million worth of electricity and hardware costs per day as part of their consensus mechanism).&lt;&#x2F;li&gt;
&lt;li&gt;Because of the lack of high electricity consumption, there is &lt;strong&gt;not as much need to issue as many new coins&lt;&#x2F;strong&gt; in order to motivate participants to keep participating in the network. It may theoretically even be possible to have negative net issuance, where a portion of transaction fees is &quot;burned&quot; and so the supply goes down over time.&lt;&#x2F;li&gt;
&lt;li&gt;Proof of stake opens the door to a wider array of techniques that use game-theoretic mechanism design in order to better &lt;strong&gt;discourage centralized cartels&lt;&#x2F;strong&gt; from forming and, if they do form, from acting in ways that are harmful to the network (e.g. like selfish mining in proof of work).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reduced centralization risks&lt;&#x2F;strong&gt;, as economies of scale are much less of an issue. $10 million of coins will get you exactly 10 times higher returns than $1 million of coins, without any additional disproportionate gains because at the higher level you can afford better mass-production equipment, which is an advantage for Proof-of-Work.&lt;&#x2F;li&gt;
&lt;li&gt;Ability to use economic penalties to &lt;strong&gt;make various forms of 51% attacks vastly more expensive&lt;&#x2F;strong&gt; to carry out than proof of work - to paraphrase Vlad Zamfir, &quot;it&#x27;s as though your ASIC farm burned down if you participated in a 51% attack&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-casper&quot;&gt;Why Casper&lt;&#x2F;h3&gt;
&lt;p&gt;There are currently three major schools of proof of stake consensus algorithm:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nakamoto-inspired&lt;&#x2F;strong&gt; (Peercoin, NXT, Ouroboros...)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PBFT-inspired&lt;&#x2F;strong&gt; (Tendermint, Casper FFG, Hotstuff...)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CBC Casper&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Within the latter two camps, there is also the question of whether and how to use security deposits and slashing (Nakamoto-inspired algorithms are incompatible with non-trivial slashing). All three are superior to proof of work, but we want to defend our own approach.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;slashing&quot;&gt;Slashing&lt;&#x2F;h4&gt;
&lt;p&gt;Ethereum 2.0 uses a &lt;strong&gt;slashing&lt;&#x2F;strong&gt; mechanism where a validator that is detected to have misbehaved can be penalized, in the best case ~1% but in the worst case up to its entire deposit.&lt;&#x2F;p&gt;
&lt;p&gt;We defend our use of slashing as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Raising the cost of attack&lt;&#x2F;strong&gt;: We want to be able to make a hard claim that a 51% attack on a proof of stake blockchain forces the attacker to incur a very large amount of expense (think: hundreds of millions of dollars worth of coins) that get burned, and any attack can be recovered from quickly. This makes the attack&#x2F;defense calculus very unfavorable for attackers, and in fact makes attacks potentially &lt;em&gt;counterproductive&lt;&#x2F;em&gt;, because the disruption to service is outweighed by price gains to legitimate coin holders.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Overcoming the validator&#x27;s dilemma&lt;&#x2F;strong&gt;: the most realistic immediate way for nodes to start to deviate from &quot;honest&quot; behavior is &lt;em&gt;laziness&lt;&#x2F;em&gt; (ie. not validating things that one should be validating, signing everything just in case, etc). See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf&quot;&gt;the validator&#x27;s dilemma paper&lt;&#x2F;a&gt; (Luu et al., CC BY) for theoretical reasoning and the Bitcoin SPV mining fork for examples of this happening and leading to very harmful consequences in the wild. Having very large penalties for self-contradicting or for signing incorrect things helps to alleviate this.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A more subtle instance of (2) can be seen as follows. In July 2019 a validator on Cosmos was slashed for signing two conflicting blocks. An investigation revealed that this happened because that validator was running a primary and a backup node (to ensure that one of the two going offline would not prevent them from getting rewards) and the two were accidentally turned on at the same time, leading to them contradicting each other.&lt;&#x2F;p&gt;
&lt;p&gt;If it became standard practice to have a primary and backup node, then an attacker could partition the network and get the primaries and the backups of all the validators to commit to different blocks, and thereby lead to two conflicting blocks being finalized. Slashing penalties help to heavily disincentivize this practice, reducing the risk of such a scenario taking place.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;choice-of-consensus-algorithm&quot;&gt;Choice of consensus algorithm&lt;&#x2F;h4&gt;
&lt;p&gt;Only the BFT-inspired and CBC schools of consensus algorithm have a notion of finality, where a block is confirmed in such a way that a large portion (1&#x2F;3 in BFT-inspired, 1&#x2F;4 in CBC) of validators would need to misbehave and get slashed for that block to get reverted in favor of some conflicting block; Nakamoto-inspired (ie. longest-chain-rule) consensus algorithms have no way of achieving finality in this sense.&lt;&#x2F;p&gt;
&lt;p&gt;Note that finality requires a (super)majority of validators being online, but this is a requirement of the sharding mechanism already, as it requires 2&#x2F;3 of a randomly sampled committee of validators to sign off on a crosslink for that crosslink to be accepted.&lt;&#x2F;p&gt;
&lt;p&gt;Our choice of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;arxiv-1710.09437-Casper-the-Friendly-Finality-Gadget.pdf&quot;&gt;Casper FFG&lt;&#x2F;a&gt; was simply a matter of it being the simplest algorithm available at the time that part of the protocol was being finalized. Details are still subject to long-term change; in particular, we are actively exploring solutions to achieve single slot finality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sharding-or-why-do-we-hate-supernodes&quot;&gt;Sharding - or, why do we hate supernodes?&lt;&#x2F;h3&gt;
&lt;p&gt;The main alternative to sharding for layer-1 scaling is the use of supernodes - simply requiring every consensus node to have a powerful server so that it can individually process every transaction. Supernode-based scaling is convenient because it is simple to implement: it works just the same way blockchains do now, except that more software-engineering work is required to build things in a way that is more parallelizable.&lt;&#x2F;p&gt;
&lt;p&gt;Our main objections to this approach are as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pool centralization risk&lt;&#x2F;strong&gt;: in a supernode-based system, running a node has a high fixed cost, so far fewer users can participate. This is usually rebutted with &quot;well consensus in most PoW and PoS coins is dominated by 5-20 pools anyway, and the pools will be able to run nodes just fine&quot;. However, this response ignores the risk of centralization pressure even between pools that can afford it. If the fixed cost of running a validator is significant relative to the returns, then larger pools will be able to offer smaller fees than smaller ones and this could lead to smaller pools being pushed out or feeling pressure to merge. In a sharded system, on the other hand, validators with more ETH need to verify more transactions, so costs are not fixed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AWS centralization risk&lt;&#x2F;strong&gt;: in a supernode-based system, home staking is infeasible and so it&#x27;s more likely that most staking will happen inside cloud computing environments, of which there are only a few options to choose from. This creates a single point of failure.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reduced censorship resistance&lt;&#x2F;strong&gt;: making it impossible to participate in consensus without high computation+bandwidth requirements makes detection and censorship of validators easier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scalability&lt;&#x2F;strong&gt;: as transaction throughput increases, in a supernode-based system the above risks increase, whereas sharded systems can more easily handle the increased load.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These centralization risks are also why we are NOT attempting to achieve super-low-latency (&amp;lt;1s) of the blockchain, instead opting for (relatively!) conservative numbers.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, Ethereum is taking an approach where each validator is only assigned to process a small portion of all data. Only validators staking large amounts of ETH (think: tens of thousands or more) are required to process the entire data in the chain.&lt;&#x2F;p&gt;
&lt;p&gt;Note that there is a possible middle-ground in sharding design where block &lt;em&gt;production&lt;&#x2F;em&gt; is centralized but (i) block &lt;em&gt;verification&lt;&#x2F;em&gt; is decentralized and (ii) there exist &quot;bypass channels&quot; where users can send transactions and block producers are forced to include them, so even a monopoly producer cannot censor. We are actively considering sharding designs that lean somewhat in this direction to increase simplicity so that scaling can be deployed faster, though if desired even within this spec it&#x27;s possible to run distributed builders and avoid centralization even there.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security-models&quot;&gt;Security models&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s commonly assumed that blockchains depend on an &quot;honest majority&quot; assumption for their security: that &amp;gt;=50% of participants will faithfully follow a prescribed protocol, even forgoing opportunities to defect for their own personal interest. In reality, (i) an honest majority model is unrealistic, with participants being &quot;lazy&quot; and signing off on blocks without validating them (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf&quot;&gt;the validator&#x27;s dilemma paper&lt;&#x2F;a&gt; and the Bitcoin SPV mining fork) being a very common form of defection, but fortunately (ii) blockchains maintain many or all of their security properties under much harsher models, and it&#x27;s really important to preserve those extra guarantees.&lt;&#x2F;p&gt;
&lt;p&gt;A common harsher model is the &lt;em&gt;uncoordinated rational majority&lt;&#x2F;em&gt; model, which states that participants act in their own self-interest, but no more than some percentage (eg. 23.21% in simple PoW chains) are cooperating with each other. An even harsher model is the worst-case model where there is a single actor that controls more than 50% of hashpower or stake, and the question becomes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Can we, even under that scenario, force the attacker to have to pay a very high cost to break the chain&#x27;s guarantees?&lt;&#x2F;li&gt;
&lt;li&gt;What guarantees can we unconditionally preserve?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Slashing in proof of stake chains accomplishes the first objective. In non-sharded chains, every node verifying every block accomplishes the second objective for two specific guarantees: (i) that the longest chain is valid, and (ii) that the longest chain is &lt;em&gt;available&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A major challenge in sharding is getting the same two properties without requiring each node to verify the full chain. Our defense-in-depth approach with sharding accomplishes just that. The core idea is to combine together random committee sampling, proof of custody, fraud proofs, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;arxiv-1809.09044-Fraud-and-Data-Availability-Proofs--Maximising-Light-Client-Security-and-Scaling-Blockchains-with-Dishonest-Majorities.pdf&quot;&gt;data availability sampling (DAS)&lt;&#x2F;a&gt; and eventually ZK-SNARKs, to allow clients to detect and reject invalid or unavailable chains without downloading and verifying all of the data, even if the invalid chains are supported by a majority of all proof of stake validators.&lt;&#x2F;p&gt;
&lt;p&gt;Censorship of transactions can potentially be detected by clients in a consensus-preserving way, but this research has not yet been incorporated into the ethereum roadmap.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the current expected security properties expressed in a table:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;Network delay &amp;lt;3s&lt;&#x2F;th&gt;&lt;th&gt;Network delay 3s - 6 min&lt;&#x2F;th&gt;&lt;th&gt;Network delay &amp;gt; 6 min&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&amp;gt;2&#x2F;3 validators honest&lt;&#x2F;td&gt;&lt;td&gt;Perfect operation&lt;&#x2F;td&gt;&lt;td&gt;Imperfect but acceptable operation. No rigorous proof of liveness, but liveness expected in practice.&lt;&#x2F;td&gt;&lt;td&gt;Likely intermittent liveness failures, no safety failures&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;gt;2&#x2F;3 validators rational, &amp;lt;1&#x2F;3 coordinated&lt;&#x2F;td&gt;&lt;td&gt;Perfect operation&lt;&#x2F;td&gt;&lt;td&gt;Imperfect but acceptable operation, heightened centralization risk&lt;&#x2F;td&gt;&lt;td&gt;Likely intermittent liveness failures, no safety failures, very high centralization risk&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;51% attacker&lt;&#x2F;td&gt;&lt;td&gt;Can revert finality or censor, but at high cost; cannot force through invalid or unavailable chains&lt;&#x2F;td&gt;&lt;td&gt;Can revert finality or censor, but at high cost; cannot force through invalid or unavailable chains&lt;&#x2F;td&gt;&lt;td&gt;Can revert finality or censor; cannot force through invalid or unavailable chains&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;why-are-the-casper-incentives-set-the-way-they-are&quot;&gt;Why are the Casper incentives set the way they are?&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;base-rewards&quot;&gt;Base rewards&lt;&#x2F;h4&gt;
&lt;p&gt;During each epoch, every validator is expected to make an &quot;attestation&quot;, a signature that expresses that validator&#x27;s opinion on what the head of the chain is. There is a reward for having one&#x27;s attestation included, with four components (called &quot;duties&quot;):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reward for the attestation getting included at all&lt;&#x2F;li&gt;
&lt;li&gt;Reward for the attestation specifying the correct epoch checkpoint&lt;&#x2F;li&gt;
&lt;li&gt;Reward for the attestation specifying the correct chain head&lt;&#x2F;li&gt;
&lt;li&gt;Reward for correctly participating in sync committee signatures&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note also that mixed into these duties is a timeliness requirement: your attestation has to be included within a certain time to be eligible for the rewards, and for the &quot;correct head&quot; duty that time limit is 1 slot.&lt;&#x2F;p&gt;
&lt;p&gt;For each duty, the actual reward is computed as follows. If:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$R = B * \frac{nom}{den}$ equals the base reward multiplied by the fraction $\frac{nom}{den}$ that corresponds to that particular duty&lt;&#x2F;li&gt;
&lt;li&gt;$P$ is the portion of validators that did the desired action&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Then:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Any validator that fulfilled the duty gets a reward of $R * P$&lt;&#x2F;li&gt;
&lt;li&gt;Any validator that did not fulfill the duty gets a penalty $-R$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The purpose of this &quot;collective reward&quot; scheme where &quot;if anyone performs better, everyone performs better&quot; is to bound griefing factors (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;ef-Discouragement-Attacks.pdf&quot;&gt;this paper&lt;&#x2F;a&gt; for one description of griefing factors and why they are important).&lt;&#x2F;p&gt;
&lt;p&gt;The base reward $B$ is itself calculated as $k * \frac{D_i}{\sqrt{\sum_{j=1}^{n} D_j}}$ where $D_1 ... D_n$ are deposit sizes and $k$ is a constant; this is a halfway compromise between two common models, (i) fixed reward rate, ie. $k * D_i$, and (ii) fixed total reward, ie. $k * \frac{D_i}{\sum_{j=1}^{n} D_j}$.&lt;&#x2F;p&gt;
&lt;p&gt;The main argument against (i) is that it imposes too much uncertainty on the network of two kinds: uncertainty of the total level of issuance, and uncertainty of the total level of deposits (as if a fixed reward rate is set too low then almost no one will participate, threatening the network, and if a rate is set too high then very many validators will participate, leading to unexpectedly high issuance). The main argument against (ii) is greater vulnerability to discouragement attacks (again see the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;ef-Discouragement-Attacks.pdf&quot;&gt;discouragement attacks paper&lt;&#x2F;a&gt;). The inverse-square-root approach compromises between the two and avoids the worst consequences of each one.&lt;&#x2F;p&gt;
&lt;p&gt;When an attestation gets a reward, the proposer gets a fraction of that reward. This is to encourage proposers to listen well for messages and accept as many as possible.&lt;&#x2F;p&gt;
&lt;p&gt;Note also that the rewards are designed to be forgiving to validators who are offline often: being offline 1% of the time only sacrifices about 1.6% of your reward. This is also to promote decentralization: the goal of a decentralized system is to create a reliable whole out of unreliable parts, so we should not be trying to force each individual node to be extremely reliable.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;inactivity-leak&quot;&gt;Inactivity leak&lt;&#x2F;h4&gt;
&lt;p&gt;If the chain fails to finalize for $tsf &amp;gt; 4$ epochs ($tsf$ = &quot;time since finality&quot;), then a penalty is added so that the maximum possible reward is zero (validators performing imperfectly get penalized), and a second penalty component is added, proportional to $tsf$ (that is, the longer the chain has not finalized, the higher the &lt;em&gt;per-epoch&lt;&#x2F;em&gt; penalty for being offline). This ensures that if more than 1&#x2F;3 of validators drop off, validators that are not online get penalized much more heavily, and the total penalty goes up quadratically over time.&lt;&#x2F;p&gt;
&lt;p&gt;This has three consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Penalizes being offline much more heavily in the case where you being offline is actually preventing blocks from being finalized&lt;&#x2F;li&gt;
&lt;li&gt;Serves the goals of being an anti-correlation penalty (see section below)&lt;&#x2F;li&gt;
&lt;li&gt;Ensures that if more than 1&#x2F;3 do go offline, eventually the portion online goes back up to 2&#x2F;3 because of the declining deposits of the offline validators&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With the current parametrization, if blocks stop being finalized, validators lose 1% of their deposits after 2.6 days, 10% after 8.4 days, and 50% after 21 days. This means for example that if 50% of validators drop offline, blocks will start finalizing again after 21 days.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;slashing-and-anti-correlation-penalties&quot;&gt;Slashing and anti-correlation penalties&lt;&#x2F;h4&gt;
&lt;p&gt;If a validator is caught violating the Casper FFG slashing condition, they get penalized a portion of their deposit equal to three times the portion of validators that were penalized around the same time as them (specifically, between 18 days before they were penalized and roughly the time they withdrew). This is motivated by several goals:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A validator misbehaving is only really bad for the network if they misbehave at the same time as many other validators, so it makes sense to punish them more in that case&lt;&#x2F;li&gt;
&lt;li&gt;It heavily penalizes actual attacks, but applies very light penalties to single isolated failures that are likely to be honest mistakes&lt;&#x2F;li&gt;
&lt;li&gt;It ensures that smaller validators take on less risk than larger validators (as in the normal case, a large validator would be the only one failing at the same time as themselves)&lt;&#x2F;li&gt;
&lt;li&gt;It creates a disincentive against everyone joining the largest pool&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bls-signatures&quot;&gt;BLS Signatures&lt;&#x2F;h3&gt;
&lt;p&gt;BLS signatures are used because of their aggregation-friendliness: any two signatures $S_1$ and $S_2$ of a message $M$ signed by keys $k_1$ and $k_2$ (corresponding pubkeys $K_1 = G * k_1$ and $K_2 = G * k_2$ where $G$ is the generator of the elliptic curve) can simply be aggregated by elliptic curve point addition: $S_1 + S_2$, which verifies against the public key $K_1 + K_2$. This allows many thousands of signatures to be aggregated, with the marginal cost of one signature being one bit of data (to express that a particular public key is present in the aggregate signature) and one elliptic curve addition for computation.&lt;&#x2F;p&gt;
&lt;p&gt;Note that BLS signatures of this form are vulnerable to &lt;em&gt;rogue key attacks&lt;&#x2F;em&gt;: if you see that other validators have already published public keys $K_1 ... K_n$, then you can generate a private key $r$ and publish a public key $G * r - K_1 - ... - K_n$. The aggregate public key would simply be $G * r$, so you would be able to make a signature that verifies against the combined public key by yourself. The standard way to get around this is to require a &lt;em&gt;proof of possession&lt;&#x2F;em&gt;: basically, a signature of a message (that depends on the public key, and that would normally not be signed) that verifies against the public key by itself (ie. $sign(message=H&#x27;(K), key=k)$ for privkey $k$ and pubkey $K$, where $H&#x27;$ is a hash function). This ensures that you personally control the private key connected to the public key that you publish.&lt;&#x2F;p&gt;
&lt;p&gt;We use the signature of a deposit message (which specifies the signing key but also other important data such as the withdrawal key) as a proof of possession.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-32-eth-validator-sizes&quot;&gt;Why 32 ETH validator sizes?&lt;&#x2F;h3&gt;
&lt;p&gt;Any BFT consensus algorithm with accountable fault tolerance (ie. if two conflicting blocks get finalized you can identify which 1&#x2F;3 of nodes were responsible) must have all validators participate, and furthermore for technical reasons you need two rounds of every validator participating to finalize a message.&lt;&#x2F;p&gt;
&lt;p&gt;This leads to the decentralization &#x2F; finality time &#x2F; overhead tradeoff: if $n$ is the number of validators in a network, $f$ is the time to finalize a block, and $\omega$ is the overhead in messages per second, then we have:&lt;&#x2F;p&gt;
&lt;p&gt;$$\omega \ge \frac{2 * n}{f}$$&lt;&#x2F;p&gt;
&lt;p&gt;For example, if we are ok with an overhead of 10 messages per second, then a 10000-node network could only have a finality time of at least 2000 seconds (~33 minutes).&lt;&#x2F;p&gt;
&lt;p&gt;In Ethereum&#x27;s case, if we assume a total ETH supply of $\approx 2^{27}$ ETH, then with 32 ETH deposit sizes, there are at most $2^{22}$ validators (and that&#x27;s if everyone validates; in general we expect ~10x less ETH validating). With a finality time of 2 epochs (2 * 32 * 12 = 768 seconds), that implies a max overhead of $\frac{2^{22}}{768} \approx 5461$ messages per second. We can tolerate such high overhead due to BLS aggregation reducing the marginal size of each signature to 1 bit and the marginal verification complexity to one elliptic curve addition.&lt;&#x2F;p&gt;
&lt;p&gt;32 slots is a safe minimum for another reason: if an attacker manipulates the randomness used for proposer selection, this number still provides enough space to ensure that there will be at least one honest proposer in each epoch, which is sufficient to ensure blocks keep finalizing. Our calculations suggest that current levels of overhead are acceptable, but higher levels would make running a node too difficult. Finally, the validator deposit size is ideal for shard crosslinking (see below).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;random-sampling&quot;&gt;Random sampling&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;seed-selection&quot;&gt;Seed selection&lt;&#x2F;h4&gt;
&lt;p&gt;The seed used for randomness is updated every block by &quot;mixing in&quot; (ie. &lt;code&gt;seed &amp;lt;- xor(seed, new_data)&lt;&#x2F;code&gt;) a value that must be revealed by the proposer of the block. Just like proof of custody subkeys, a validator&#x27;s values are all pre-determined once the validator has deposited, third parties cannot compute subkeys but can verify subkeys that are revealed voluntarily (this mechanism is sometimes called RANDAO).&lt;&#x2F;p&gt;
&lt;p&gt;This ensures that each proposer has one &quot;bit of manipulation&quot; over the seed: they can either make a block or not make a block. Not making a block is expensive in that the proposer misses out on many rewards. Furthermore, because the persistent and beacon committee sizes (see below) are large, manipulation of the randomness almost certainly cannot allow minority attackers to get 2&#x2F;3 of any committee.&lt;&#x2F;p&gt;
&lt;p&gt;In the future we plan to use verifiable delay functions (VDFs) to further increase the random seeds&#x27; robustness against manipulation.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;shuffling&quot;&gt;Shuffling&lt;&#x2F;h4&gt;
&lt;p&gt;We use the swap-or-not shuffle described by Viet Tung Hoang, Ben Morris, and Phillip Rogaway to shuffle the validator set and assign responsibilities every epoch. This algorithm ensures that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;As the shuffle is a permutation, each validator is assigned to be a member of exactly one committee during each epoch (keeping their load stable and reducing the chance manipulation of randomness can be profitable)&lt;&#x2F;li&gt;
&lt;li&gt;As the shuffle is pointwise-evaluable in the forward direction, a validator can determine their own responsibilities in O(1) time&lt;&#x2F;li&gt;
&lt;li&gt;As the shuffle is pointwise-evaluable in the reverse direction, the members of any specific committee or the proposer of any specific block can be computed in O(1) time&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;shuffling-by-slot&quot;&gt;Shuffling by slot&lt;&#x2F;h4&gt;
&lt;p&gt;There are 32 slots in an epoch, and the validators responsible for attesting to each slot are chosen by shuffling. This ensures that attackers with a significant but still small portion of total stake cannot take over specific slots and cause short-range reorgs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;beacon-committees&quot;&gt;Beacon committees&lt;&#x2F;h4&gt;
&lt;p&gt;The committee for each slot is in turn split up into some number of &lt;em&gt;beacon committees&lt;&#x2F;em&gt;. Today (2022 Jan), this design does serve one useful function, allowing different subsets of attestations to get aggregated in separate subnets and thus making the p2p network more efficient. However, it does not serve any other useful consensus-related role.&lt;&#x2F;p&gt;
&lt;p&gt;In the original sharding design, the intention was that each beacon committee would be responsible for verifying a specific shard. However, this approach is likely deprecated if we switch to a single-proposer model. Hence, the more fine-grained beacon committees may well only be there vestigially and could eventually be removed or re-structured in a different way to focus on facilitating attestation aggregation.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sync-committee&quot;&gt;Sync committee&lt;&#x2F;h4&gt;
&lt;p&gt;A sync committee of 512 validators is selected once every ~27 hours to sign a block; this committee&#x27;s pubkeys are saved in an easily accessible list, allowing signatures to be easily verified by ultra-light clients.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lmd-ghost-fork-choice-rule&quot;&gt;LMD GHOST fork choice rule&lt;&#x2F;h3&gt;
&lt;p&gt;The beacon chain uses an LMD GHOST fork choice rule.&lt;&#x2F;p&gt;
&lt;p&gt;The LMD GHOST fork choice rule incorporates information from all validators, hundreds in each slot, making it extremely unlikely in the normal case that even a single block will be reverted. Because the fork choice is dependent on all validators, this also ensures that blocks cannot be reverted unless an attacker really does control close to 50% of the entire validator set; one cannot achieve a large advantage by manipulating the randomness.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-proof-of-custody-game&quot;&gt;The proof of custody game&lt;&#x2F;h3&gt;
&lt;p&gt;For each 9-day period, each validator has the ability to privately generate a &quot;period subkey&quot;. The validator&#x27;s public key uniquely determines their period subkey for every period, so once a validator has deposited they have no further freedom to choose what their subkeys are. No one can compute any given validator&#x27;s subkey except the validator themselves, but once a validator reveals a subkey voluntarily, anyone can verify its correctness (this is all done via BLS magic, and if quantum-safety is required in the future it can be done with hash-based commitments).&lt;&#x2F;p&gt;
&lt;p&gt;When signing a block with data $D$ with root $R$ during period $j$, letting $s$ being the period-$j$ secret of that validator, a validator is required to compute a bitfield $M$ as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Split $D$ into 512-byte chunks $D[0] ... D[n-1]$&lt;&#x2F;li&gt;
&lt;li&gt;Set $M$ to be the bitfield where the i&#x27;th bit is $M[i] = mix(s, D[i])$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;They include &lt;code&gt;get_chunk_bits_root(M)&lt;&#x2F;code&gt; (this is called the &lt;strong&gt;custody bit&lt;&#x2F;strong&gt;) as part of what they are signing. &lt;code&gt;mix&lt;&#x2F;code&gt; and &lt;code&gt;get_chunk_bits_root&lt;&#x2F;code&gt; can both be viewed as hash-like functions that output a single bit (but are designed for multi-party-computation friendliness).&lt;&#x2F;p&gt;
&lt;p&gt;If a crosslink includes multiple blocks $B_1 ... B_n$ and the validator computes custody bits $c_1 ... c_n$ for these blocks, then the validator signs all $(B_i, c_i, i)$ tuples and aggregates them. This unconventional self-aggregation is used to ensure that there are only $2n$ different messages (n different block&#x2F;index pairs * 2 different bit values) being signed by different validators, reducing the number of pairings needed to verify the signatures.&lt;&#x2F;p&gt;
&lt;p&gt;If a validator publishes their period $j$ subkey during or before period $j$, any other validator can publish a proof-of-knowledge of the subkey to the chain, which then penalizes the validator whose subkey was revealed. The proof of knowledge also proves which validator created it; this prevents block proposers from &quot;stealing&quot; the whistleblowing reward (once again all done via BLS magic, if quantum-safety is required in the future this can be done with STARKs). The goal of this is to make it dangerous to outsource computation of $M$.&lt;&#x2F;p&gt;
&lt;p&gt;After a validator publishes their period $j$ subkey, anyone else can check their work for any block that they signed. If they discover that a validator provided an incorrect custody bit, they can challenge this on-chain, and slash that validator. In general, random guessing (or any procedure that does not involve all of $D$) will only give a correct answer half the time, leading to a 50% risk of slashing per block signed.&lt;&#x2F;p&gt;
&lt;p&gt;The purpose of this mechanism is to mitigate the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf&quot;&gt;validator&#x27;s dilemma&lt;&#x2F;a&gt; problem, where validators have an incentive to avoid verifying data out of laziness and piggyback on the assumption that all &lt;em&gt;other&lt;&#x2F;em&gt; validators are honest; if too many validators think in this way, it could lead to a tragedy of the commons leading to the chain accepting invalid blocks. With this scheme, if a validator attempts to commit to data that they did not personally process, then they would not be able to compute $M$, and so would lose the interactive challenge game.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ssz&quot;&gt;SSZ&lt;&#x2F;h3&gt;
&lt;p&gt;The SimpleSerialize suite contains the following algorithms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A serialization algorithm&lt;&#x2F;li&gt;
&lt;li&gt;A hashing algorithm (called &lt;code&gt;SSZTreeHash&lt;&#x2F;code&gt; or &lt;code&gt;hash_tree_root&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;A generalized Merkle proof algorithm (called &quot;SSZ partials&quot;) that can handle proofs for multiple values and optimally deduplicates Merkle tree sister nodes in such cases.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The serialization algorithm has the following design goals:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simplicity (eg. no three clauses like RLP has for long &#x2F; list encoding depending on item length)&lt;&#x2F;li&gt;
&lt;li&gt;Being equivalent to simple concatenation in the case of entirely fixed-size objects&lt;&#x2F;li&gt;
&lt;li&gt;Being usable as both a consensus-layer serialization algorithm and an application-layer ABI&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that the resulting SSZ serialization spec is very similar to the ethereum 1.0 ABI, with the major differences being (i) different basic data types and (ii) replacing the 32 byte length&#x2F;position record size with a 4 byte size.&lt;&#x2F;p&gt;
&lt;p&gt;The hashing algorithm has the following design goals:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Efficiency of computing the hash of an updated object, especially in the case where the object is very large and&#x2F;or complex and the change is relatively small&lt;&#x2F;li&gt;
&lt;li&gt;Efficiency (in terms of verification complexity &lt;em&gt;and&lt;&#x2F;em&gt; witness size) of proving the value of a specific field even in a large or complex object with a given hash&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These requirements together make a Merkle tree structure the obvious choice.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;generalized-indices&quot;&gt;Generalized indices&lt;&#x2F;h4&gt;
&lt;p&gt;See https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;eth2.0-specs&#x2F;blob&#x2F;dev&#x2F;ssz&#x2F;merkle-proofs.md for a description of generalized indices, and how they allow for very easy verification of Merkle proofs &quot;poking into&quot; arbitrary positions in an object by representing paths as an integer or bitfield.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-validator-lifecycle&quot;&gt;The validator lifecycle&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;depositing&quot;&gt;Depositing&lt;&#x2F;h4&gt;
&lt;p&gt;A validator deposits by sending a transaction that calls a function on the deposit contract on the eth1 chain (eventually, a way to deposit from inside eth2 will also be added). A deposit specifies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The public key corresponding to the private key that will be used to sign messages&lt;&#x2F;li&gt;
&lt;li&gt;The withdrawal credentials (hash of the public key that will be used to withdraw funds once the validator is done validating)&lt;&#x2F;li&gt;
&lt;li&gt;The deposit amount&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These values are all signed by the signing key. The goal of having separate signing and withdrawal keys is to allow the more dangerous withdrawal key to be kept more securely (offline, not shared with any staking pools, etc) while the signing key is used to actively sign a message every epoch.&lt;&#x2F;p&gt;
&lt;p&gt;The deposit contract maintains a Merkle root of all deposits made so far. Once a merkle root containing the deposit gets included into the eth2 chains (via the Eth1Data voting mechanism), an eth2 block proposer can submit a Merkle proof of the deposit and start the deposit process.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h4&gt;
&lt;p&gt;The validator immediately joins the validator registry, but is at first inactive. The validator becomes active after $N \ge 4$ epochs; the minimum of 4 is there to ensure the RANDAO is not manipulable, and $N$ may exceed 4 if too many validators try to join at the same time. If the active validator set has size $|V|$, a maximum of $max(4, \frac{|V|}{65536})$ validators can join per epoch; if more validators try to join, they are put in a queue and processed as quickly as possible.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;exiting&quot;&gt;Exiting&lt;&#x2F;h4&gt;
&lt;p&gt;When a validator exits (whether by publishing a voluntary exit message or being slashed), they are similarly put into an exit queue with the same maximum throughput.&lt;&#x2F;p&gt;
&lt;p&gt;The reason for the entrance&#x2F;exit queue limits is to ensure that the validator set cannot change too quickly between any two points in time, which ensures that finality guarantees still remain between two chains as long as a validator logs on often enough (once every ~1-2 months if $|V| \ge 262144$). See here https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;rate-limiting-entry-exits-not-withdrawals&#x2F;4942 for rationale (and specifically why to use a rate limit instead of a fixed waiting time) and https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;weak-subjectivity-under-the-exit-queue-model&#x2F;5187 for how to calculate safety margin for a client that has been offline for some amount of time.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;withdrawal&quot;&gt;Withdrawal&lt;&#x2F;h4&gt;
&lt;p&gt;Once a validator leaves the exit queue, there is a ~27 hour period until they can withdraw. This period has several functions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It ensures that if a validator misbehaved there is a period of time within which the error can be caught and the validator can be slashed even if the exit queue is nearly empty.&lt;&#x2F;li&gt;
&lt;li&gt;It provides time for the last period of shard rewards to be included.&lt;&#x2F;li&gt;
&lt;li&gt;It provides time for proof of custody challenges to be made.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If a validator is slashed, a further delay of ~36 days is imposed. This further penalizes them (and forces them to hold the ETH; this makes the penalty somewhat larger for malicious validators that are trying to destroy the ethereum blockchain than those validators that want to support the platform but just made a mistake, as the former category would have to risk the exposure or pay for derivatives to cancel it out), but also allows for a period during which the number of other validators that got slashed can be calculated.&lt;&#x2F;p&gt;
&lt;p&gt;In phase 0, a &quot;withdrawn&quot; validator cannot actually withdraw to anywhere yet; the only distinction is that it is protected from validator penalties and does not have any responsibilities. In later phases, the ability to move funds from a withdrawn validator slot to an execution environment will be made available.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;effective-balances&quot;&gt;Effective balances&lt;&#x2F;h4&gt;
&lt;p&gt;Most calculations based on a validator&#x27;s balance use the validator&#x27;s &quot;effective balance&quot;; the only exception is calculations that increase or decrease the validator&#x27;s balance. Only when the validators&#x27;s balance $B$ falls below $EB$ or goes above $EB + 1.5$ is $EB$ adjusted to equal $floor(B)$. This is done to ensure that effective balance changes infrequently, reducing the amount of hashing needed to recompute the state every epoch; on average, only the balances need to all be updated, and the effective balances only get updated relatively rarely per validator. Balances are all stored in a dedicated vector, so $2 * \frac{N * 8}{32} = \frac{N}{2}$ hashes are needed to recompute a balance array, whereas effective balances are stored in validator record objects, where at least $5N$ hashes would be needed per validator to adjust the SSZ hash roots. Additionally, $EB$ can be compressed more easily into a CompactValidator object, as it&#x27;s only one byte.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fork-mechanism&quot;&gt;Fork mechanism&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;Fork&lt;&#x2F;code&gt; data structure contains (i) the current &quot;fork ID&quot;, (ii) the previous fork ID and (iii) the switchover slot. The fork ID at the current height influences the valid signatures of all messages; hence, a message signed with one fork ID is invalid to a verification function using any other fork ID.&lt;&#x2F;p&gt;
&lt;p&gt;A fork is done by adding a state transition at some &quot;fork slot&quot; $n$ which sets the previous fork ID to the current fork ID, the current fork ID to a new value, and the switchover slot to $n$. Signature verification functions will verify messages using the fork ID at the slot the message is for, which could be the previous fork ID or the current one (eg. consider the case of attestations included after a delay; an attestation from before the fork slot could be included after the fork slot).&lt;&#x2F;p&gt;
&lt;p&gt;If any users do not want to join the fork, they can simply continue the chain that does not change the fork ID at the fork slot. The two chains would be able to proceed and validators would be free to validate on both without getting slashed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Although this EIP does not introduce any immediate changes to the current Ethereum mainnet, this EIP lays the groundwork for future backwards incompatibilities through the introduction of the new eth2 consensus mechanism in which Ethereum will be integrated in subsequent phases. To secure this mechanism, users move ether into the beacon chain and additional ether is issued. This EIP is a commitment to this path being canonical, as well as directly informing the future and roadmap of Ethereum mainnet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Eth2 is a major overhaul of the Ethereum&#x27;s core consensus from PoW to a sharded PoS. There are inherent risks in this migration but there is extensive research literature analyzing security and trade-offs. &lt;em&gt;The following only represents a high level selection of the resources available:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;arxiv-1710.09437-Casper-the-Friendly-Finality-Gadget.pdf&quot;&gt;Casper FFG&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2982&#x2F;.&#x2F;assets&#x2F;arxiv-2003.03052-Combining-GHOST-and-Casper.pdf&quot;&gt;Combining GHOST and Casper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In addition to the research supporting this path, a number of audits and formal verification of specs, cryptography, and client implementations have been performed. &lt;em&gt;Many client and utility library audits are currently in progress and will be appended here upon completion.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Typed Transactions over Gossip</title>
        <published>2020-09-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/MicahZoltu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2976/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2976-eth-typed-transactions-over-gossip/4610" />
        

        <id>https://wg-eips.ritovision.com/2976/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2976"
            label="EIP-2976" />
        

        
        

        
        <summary type="html">Adds support for transmission of typed transactions over devp2p.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2976/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;Typed Transactions&lt;&#x2F;a&gt; can be sent over devp2p as &lt;code&gt;TransactionType || TransactionPayload&lt;&#x2F;code&gt;.
The exact contents of the &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; are defined by the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; in future EIPs, and clients may start supporting their gossip without incrementing the devp2p version.
If a client receives a &lt;code&gt;TransactionType&lt;&#x2F;code&gt; that it doesn&#x27;t recognize, it &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; disconnect from the peer who sent it.
Clients &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; send new transaction types before they believe the fork block is reached.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; introduced new transaction types for blocks (which presents itself in the makeup of a block header&#x27;s transaction root and receipts root).
However, without a mechanism for gossiping these transactions, no one can actually include them in a block.
By updating devp2p to support the gossip of Typed Transactions, we can benefit from these new transaction types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; for additional motivations of Typed Transactions.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;All changes specified below apply to all protocol&#x2F;versions retroactively.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;||&lt;&#x2F;code&gt; is the byte&#x2F;byte-array concatenation operator.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;|&lt;&#x2F;code&gt; is the type union operator.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DEVP2P_VERSION = TBD&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Transaction&lt;&#x2F;code&gt; is either &lt;code&gt;TypedTransaction&lt;&#x2F;code&gt; or &lt;code&gt;LegacyTransaction&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TypedTransaction&lt;&#x2F;code&gt; is a byte array containing &lt;code&gt;TransactionType || TransactionPayload&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TypedTransactionHash&lt;&#x2F;code&gt; is &lt;code&gt;keccak256(TypedTransaction)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionType&lt;&#x2F;code&gt; is a positive unsigned 8-bit number between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;0x7f&lt;&#x2F;code&gt; that represents the type of the transaction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; is an opaque byte array whose interpretation is dependent on the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; and defined in future EIPs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyTransaction&lt;&#x2F;code&gt; is an array of the form &lt;code&gt;[nonce, gasPrice, gasLimit, to, value, data, v, r, s]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyTransactionHash&lt;&#x2F;code&gt; is &lt;code&gt;keccak256(rlp(LegacyTransaction))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionId&lt;&#x2F;code&gt; is &lt;code&gt;keccak256(TypedTransactionHash | LegacyTransactionHash)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Receipt&lt;&#x2F;code&gt; is either &lt;code&gt;TypedReceipt&lt;&#x2F;code&gt; or &lt;code&gt;LegacyReceipt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TypedReceipt&lt;&#x2F;code&gt; is a byte array containing &lt;code&gt;TransactionType || ReceiptPayload&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; is an opaque byte array whose interpretation is dependent on the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; and defined in future EIPs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyReceipt&lt;&#x2F;code&gt; is an array of the form &lt;code&gt;[status, cumulativeGasUsed, logsBloom, logs]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyReceiptHash&lt;&#x2F;code&gt; is &lt;code&gt;keccak256(rlp(LegacyReceipt))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;protocol-behavior&quot;&gt;Protocol Behavior&lt;&#x2F;h3&gt;
&lt;p&gt;If a client receives a &lt;code&gt;TransactionType&lt;&#x2F;code&gt; it doesn&#x27;t recognize via any message, it &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; disconnect the peer that sent it.&lt;&#x2F;p&gt;
&lt;p&gt;If a client receives a &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; that isn&#x27;t valid for the &lt;code&gt;TransactionType&lt;&#x2F;code&gt;, it &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; disconnect the peer that sent it.&lt;&#x2F;p&gt;
&lt;p&gt;Clients &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; send transactions of a new &lt;code&gt;TransactionType&lt;&#x2F;code&gt; until that transaction type&#x27;s introductory fork block.&lt;&#x2F;p&gt;
&lt;p&gt;Clients &lt;strong&gt;MAY&lt;&#x2F;strong&gt; disconnect peers who send transactions of a new &lt;code&gt;TransactionType&lt;&#x2F;code&gt; significantly before that transaction type&#x27;s introductory fork block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;protocol-messages&quot;&gt;Protocol Messages&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;Transactions (0x02)&lt;&#x2F;code&gt;: &lt;code&gt;[Transaction_0, Transaction_1, ..., Transaction_n]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;BlockBodies (0x06)&lt;&#x2F;code&gt;: &lt;code&gt;[BlockBody_0, BlockBody_1, ..., BlockBody_n]&lt;&#x2F;code&gt; where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BlockBody&lt;&#x2F;code&gt; is &lt;code&gt;[TransactionList, UncleList]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionList&lt;&#x2F;code&gt; is &lt;code&gt;[Transaction_0, Transaction_1, ..., Transaction_n]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;UnclesList&lt;&#x2F;code&gt; is defined in previous versions of the devp2p specification&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt;: &lt;code&gt;[[BlockHeader, TransactionList, UncleList], TotalDifficulty]&lt;&#x2F;code&gt; where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BlockHeader&lt;&#x2F;code&gt; is defined in previous versions of the devp2 specification&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionList&lt;&#x2F;code&gt; is &lt;code&gt;[Transaction_0, Transaction_1, ..., Transaction_n]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;UnclesList&lt;&#x2F;code&gt; is defined in previous versions of the devp2p specification&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TotalDifficulty&lt;&#x2F;code&gt; is defined in previous versions of the devp2p specification&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;NewPooledTransactionIds (0x08)&lt;&#x2F;code&gt;: &lt;code&gt;[TransactionId_0, TransactionId_1, ..., TransactionId_n]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt;: &lt;code&gt;[TransactionId_0, TransactionId_1, ..., TransactionId_n]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt;: &lt;code&gt;[Transaction_0, Transaction_1, ..., Transaction_n]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Receipts (0x10)&lt;&#x2F;code&gt;: &lt;code&gt;[ReceiptList_0, ReceiptList_1, ..., ReceiptList_n]&lt;&#x2F;code&gt; where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ReceiptList&lt;&#x2F;code&gt; is &lt;code&gt;[Receipt_0, Receipt_1, ..., Receipt_n]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-not-specify-each-transaction-type-at-the-protocol-layer&quot;&gt;Why not specify each transaction type at the protocol layer?&lt;&#x2F;h3&gt;
&lt;p&gt;We could have chosen to make the protocol aware of the shape of the transaction payloads.
The authors felt that it would be too much maintenance burden long term to have every new transaction type require an update to devp2p, so instead we merely define that typed transactions are supported.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-have-peers-disconnect-if-they-receive-an-unknown-transaction-type&quot;&gt;Why have peers disconnect if they receive an unknown transaction type?&lt;&#x2F;h3&gt;
&lt;p&gt;We could encourage peers to remain connected to peers that submit an unknown transaction type, in case the transaction is some new transaction type that the receiver isn&#x27;t aware of it.
However, doing so may open clients up to DoS attacks where someone would send them transactions of an undefined &lt;code&gt;TransactionType&lt;&#x2F;code&gt; in order to avoid being disconnected for spamming.
Also, in most cases we expect that by the time new transaction types are being sent over devp2p, a hard fork that requires all connected clients to be aware of the new transaction type is almost certainly imminent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Legacy transactions are still supported.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;If a client chooses to ignore the &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; recommendation for disconnecting peers that send unknown transaction types they may be susceptible to DoS attacks.
Ignoring this recommendation should be limited to trusted peers only, or other situations where the risk of DoS is extremely low.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Serve historical block hashes from state</title>
        <published>2020-09-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Tomasz Stanczak</name><uri>https://github.com/tkstanczak</uri>
	</author>
	
	<author>
		<name>Guillaume Ballet</name><uri>https://github.com/gballet</uri>
	</author>
	
	<author>
		<name>Gajinder Singh</name><uri>https://github.com/g11tech</uri>
	</author>
	
	<author>
		<name>Tanishq Jasoria</name><uri>https://github.com/tanishqjasoria</uri>
	</author>
	
	<author>
		<name>Ignacio Hagopian</name><uri>https://github.com/jsign</uri>
	</author>
	
	<author>
		<name>Jochem Brouwer</name><uri>https://github.com/jochem-brouwer</uri>
	</author>
	
	<author>
		<name>Sina Mahmoodi</name><uri>https://github.com/s1na</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2935/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2935-save-historical-block-hashes-in-state/4565" />
        

        <id>https://wg-eips.ritovision.com/2935/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2935"
            label="EIP-2935" />
        

        
        

        
        <summary type="html">Store and serve last 8191 block hashes as storage slots of a system contract to allow for stateless execution</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2935/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Store last &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; historical block hashes in the storage of a system contract as part of the block processing logic. Furthermore this EIP has no impact on &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; resolution mechanism (and hence its range&#x2F;costs etc).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;EVM implicitly assumes the client has the recent block (hashes) at hand. This assumption is not future-proof given the prospect of stateless clients. Including the block hashes in the state will allow bundling these hashes in the witness provided to a stateless client. This is already possible in the MPT and will become more efficient post-Verkle.&lt;&#x2F;p&gt;
&lt;p&gt;Extending the range of blocks which &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; can serve (&lt;code&gt;BLOCKHASH_SERVE_WINDOW&lt;&#x2F;code&gt;) would have been a semantics change. Using extending that via this contract storage would allow a soft-transition. Rollups can benefit from the longer history window through directly querying this contract.&lt;&#x2F;p&gt;
&lt;p&gt;A side benefit of this approach could be that it allows building&#x2F;validating proofs related to last &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; ancestors directly against the current state.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOCKHASH_SERVE_WINDOW&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;256&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;8191&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x0000F90827F1C53a10cb7A02335B175320002935&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;This EIP specifies for storing last &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; block hashes in a ring buffer storage of &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; length. Note that &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; &amp;gt; &lt;code&gt;BLOCKHASH_SERVE_WINDOW&lt;&#x2F;code&gt; (which remains unchanged).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-processing&quot;&gt;Block processing&lt;&#x2F;h3&gt;
&lt;p&gt;At the start of processing any block where this EIP is active (ie. before processing any transactions), call to &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; as &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; with the 32-byte input of &lt;code&gt;block.parent.hash&lt;&#x2F;code&gt;, a gas limit of &lt;code&gt;30_000_000&lt;&#x2F;code&gt;, and &lt;code&gt;0&lt;&#x2F;code&gt; value. This will trigger the &lt;code&gt;set()&lt;&#x2F;code&gt; routine of the history contract. This is a system operation following the same convention as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt; and therefore:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the call must execute to completion&lt;&#x2F;li&gt;
&lt;li&gt;the call does not count against the block&#x27;s gas limit&lt;&#x2F;li&gt;
&lt;li&gt;the call does not follow the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1559&#x2F;&quot;&gt;EIP-1559&lt;&#x2F;a&gt; burn semantics - no value should be transferred as part of the call&lt;&#x2F;li&gt;
&lt;li&gt;if no code exists at &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt;, the call must fail silently&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note: Alternatively clients can choose to directly write to the storage of the contract but EVM calling the contract remains preferred. Refer to the rationale for more info.&lt;&#x2F;p&gt;
&lt;p&gt;Note that, it will take &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; blocks after the EIP&#x27;s activation to completely fill up the ring buffer. The contract will only contain the parent hash of the fork block and no hashes prior to that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;evm-changes&quot;&gt;EVM Changes&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; opcode semantics remains the same as before.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-hash-history-contract&quot;&gt;Block hash history contract&lt;&#x2F;h3&gt;
&lt;p&gt;The history contract has two operations: &lt;code&gt;get&lt;&#x2F;code&gt; and &lt;code&gt;set&lt;&#x2F;code&gt;. The &lt;code&gt;set&lt;&#x2F;code&gt; operation is invoked only when the &lt;code&gt;caller&lt;&#x2F;code&gt; is equal to the &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; as per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt;. Otherwise the &lt;code&gt;get&lt;&#x2F;code&gt; operation is performed.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;get&quot;&gt;&lt;code&gt;get&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;It is used from the EVM for looking up block hashes.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Callers provide the block number they are querying in a big-endian encoding.&lt;&#x2F;li&gt;
&lt;li&gt;If calldata is not 32 bytes, revert.&lt;&#x2F;li&gt;
&lt;li&gt;For any request outside the range of [block.number-&lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt;, block.number-1], revert.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;set&quot;&gt;&lt;code&gt;set&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Caller provides &lt;code&gt;block.parent.hash&lt;&#x2F;code&gt; as calldata to the contract.&lt;&#x2F;li&gt;
&lt;li&gt;Set the storage value at &lt;code&gt;block.number-1 % HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; to be &lt;code&gt;calldata[0:32]&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;bytecode&quot;&gt;Bytecode&lt;&#x2F;h4&gt;
&lt;p&gt;Exact evm assembly that can be used for the history contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; https:&#x2F;&#x2F;github.com&#x2F;lightclient&#x2F;sys-asm&#x2F;blob&#x2F;f1c13e285b6aeef2b19793995e00861bf0f32c9a&#x2F;src&#x2F;execution_hash&#x2F;main.eas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push20 0xfffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push2 0x1fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dup2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push2 0x1fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jumpdest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push2 0x1fff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push1 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sstore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;deployment&quot;&gt;Deployment&lt;&#x2F;h4&gt;
&lt;p&gt;A special synthetic address is generated by working backwards from the desired deployment transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3d090&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe8d4a51000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxPriorityFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;maxFeePerGas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x60538060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x539&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xaa12693182426612186309f02cfe8a80a0000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x67139a552b0d3fffc30c0fa7d0c20d42144138c8fe07fc5691f09c1cce632e15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;Note, the input in the transaction has a simple constructor prefixing the desired runtime code.&lt;&#x2F;p&gt;
&lt;p&gt;The sender of the transaction can be calculated as &lt;code&gt;0x3462413Af4609098e1E27A490f554f260213D685&lt;&#x2F;code&gt;. The address of the first contract deployed from the account is &lt;code&gt;rlp([sender, 0])&lt;&#x2F;code&gt; which equals &lt;code&gt;0x0000F90827F1C53a10cb7A02335B175320002935&lt;&#x2F;code&gt;. This is how &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; is determined. Although this style of contract creation is not tied to any specific initcode like create2 is, the synthetic address is cryptographically bound to the input data of the transaction (e.g. the initcode).&lt;&#x2F;p&gt;
&lt;p&gt;Some activation scenarios:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For the fork to be activated at genesis, no history is written to the genesis state, and at the start of block &lt;code&gt;1&lt;&#x2F;code&gt;, genesis hash will be written as a normal operation to slot &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;for activation at block &lt;code&gt;1&lt;&#x2F;code&gt;, only genesis hash will be written at slot &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;for activation at block &lt;code&gt;32&lt;&#x2F;code&gt;, block &lt;code&gt;31&lt;&#x2F;code&gt;&#x27;s hash will be written to slot &lt;code&gt;31&lt;&#x2F;code&gt;. Every other slot will be &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;eip-161-handling&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;161&#x2F;&quot;&gt;EIP-161&lt;&#x2F;a&gt; handling&lt;&#x2F;h3&gt;
&lt;p&gt;The bytecode above will be deployed à la &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt;. As such the account at &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; will have code and a nonce of 1, and will be exempt from EIP-161 cleanup.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-costs&quot;&gt;Gas costs&lt;&#x2F;h3&gt;
&lt;p&gt;The system update at the beginning of the block, i.e. &lt;code&gt;process_block_hash_history&lt;&#x2F;code&gt; (or via system call to the contract with &lt;code&gt;SYSTEM_ADDRESS&lt;&#x2F;code&gt; caller), will not warm the &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; account or its storage slots as per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt; rules. As such the first call to the contract will pay for warming up the account and storage slots it accesses.To clarify further any contract call to the &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; will follow normal EVM execution semantics.&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; semantics doesn&#x27;t change, this EIP has no impact on &lt;code&gt;BLOCKHASH&lt;&#x2F;code&gt; mechanism and costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Very similar ideas were proposed before. This EIP is a simplification, removing two sources of needless complexity:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Having a tree-like structure with multiple layers as opposed to a single list&lt;&#x2F;li&gt;
&lt;li&gt;Writing the EIP in EVM code&lt;&#x2F;li&gt;
&lt;li&gt;Serial unbounded storage of hashes for a deep access to the history&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;However after weighing pros and cons, we decided to go with just a limited ring buffer to only serve the requisite &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt; and beacon state accumulators allow (albeit a bit more complex) proof against any ancestor since merge.&lt;&#x2F;p&gt;
&lt;p&gt;Second concern was how to best transition the BLOCKHASH resolution logic post fork by:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Either waiting for  &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; blocks for the entire relevant history to persist&lt;&#x2F;li&gt;
&lt;li&gt;Storing of all last &lt;code&gt;HISTORY_SERVE_WINDOW&lt;&#x2F;code&gt; block hashes on the fork block.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We choose to go with the former. It simplifies the logic greatly. It will take roughly a day to bootstrap the contract. Given that this is a new way of accessing history and no contract depends on it, it is deemed a favorable tradeoff.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inserting-the-parent-block-hash&quot;&gt;Inserting the parent block hash&lt;&#x2F;h3&gt;
&lt;p&gt;Clients have generally two options for inserting the parent block hash into state:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Performing a system call to &lt;code&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;code&gt; and letting that handle the storing in state.&lt;&#x2F;li&gt;
&lt;li&gt;Avoid EVM processing and directly write to the state trie.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The latter option is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; process_block_hash_history&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; state&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; FORK_TIMESTAMP&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; FORK_TIMESTAMP&lt;&#x2F;span&gt;&lt;span&gt; should&lt;&#x2F;span&gt;&lt;span&gt; be&lt;&#x2F;span&gt;&lt;span&gt; defined&lt;&#x2F;span&gt;&lt;span&gt; outside&lt;&#x2F;span&gt;&lt;span&gt; of&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; EIP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        state&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;insert_slot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;HISTORY_STORAGE_ADDRESS&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; HISTORY_SERVE_WINDOW&lt;&#x2F;span&gt;&lt;span&gt; ,&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hash&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 option is recommended until the Verkle fork, to stay consistent with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;4788&#x2F;&quot;&gt;EIP-4788&lt;&#x2F;a&gt; and to issues for misconfigured networks where this EIP is activated but history contract hasn&#x27;t been deployed. The recommendation may be reconsidered at the Verkle fork if filtering the system contract code chunks is deemed too complex.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;size-of-ring-buffers&quot;&gt;Size of ring buffers&lt;&#x2F;h3&gt;
&lt;p&gt;The ring buffer data structure is sized to hold 8191 hashes. In other system contracts a prime ring buffer size is chosen in because using a prime as the modulus ensures that no value is overwritten until the entire ring buffer has been saturated and thereafter, each value will be updated once per iteration, regardless of if some slot are missing or the slot time changes. However, in this EIP the block number is the value in the modulo operation and it only ever increases by 1 each iteration. Which means we can be confident that the ring buffer will always remain saturated.&lt;&#x2F;p&gt;
&lt;p&gt;For consistency with other system contracts, we have decided to retain the buffer size of 8191. Given the current mainnet values, 8191 roots provides about a day of coverage. This also gives users plenty of time to make a transaction with a verification against a specific hash and get the transaction included on-chain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces backwards incompatible changes to the block validation rule set. But neither of these changes break anything related to current user activity and experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;tree&#x2F;3810d22f84f206866f66f4f6bf856187c2893ab1&#x2F;tests&#x2F;prague&#x2F;eip2935_historical_block_hashes_from_state&quot;&gt;EIP-2935 Execution Spec Tests&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Having contracts (system or otherwise) with hot update paths (branches) poses a risk of &quot;branch&quot; poisoning attacks where attacker could sprinkle trivial amounts of eth around these hot paths (branches). But it has been deemed that cost of attack would escalate significantly to cause any meaningful slow down of state root updates.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Gas cost increases for state access opcodes</title>
        <published>2020-09-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Martin Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2929/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2929-gas-cost-increases-for-state-access-opcodes/4558" />
        

        <id>https://wg-eips.ritovision.com/2929/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:2929"
            label="EIP-2929" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2929/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Increases gas cost for &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, &lt;code&gt;*CALL&lt;&#x2F;code&gt;, &lt;code&gt;BALANCE&lt;&#x2F;code&gt;, &lt;code&gt;EXT*&lt;&#x2F;code&gt; and &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; when used for the first time in a transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Increase the gas cost of &lt;code&gt;SLOAD&lt;&#x2F;code&gt; (&lt;code&gt;0x54&lt;&#x2F;code&gt;) to 2100, and the &lt;code&gt;*CALL&lt;&#x2F;code&gt; opcode family (&lt;code&gt;0xf1&lt;&#x2F;code&gt;, &lt;code&gt;f2&lt;&#x2F;code&gt;, &lt;code&gt;f4&lt;&#x2F;code&gt;, &lt;code&gt;fA&lt;&#x2F;code&gt;), &lt;code&gt;BALANCE&lt;&#x2F;code&gt; &lt;code&gt;0x31&lt;&#x2F;code&gt; and the &lt;code&gt;EXT*&lt;&#x2F;code&gt; opcode family (&lt;code&gt;0x3b&lt;&#x2F;code&gt;, &lt;code&gt;0x3c&lt;&#x2F;code&gt;, &lt;code&gt;0x3f&lt;&#x2F;code&gt;) to 2600. Exempts (i) precompiles, and (ii) addresses and storage slots that have already been accessed in the same transaction, which get a decreased gas cost. Additionally reforms &lt;code&gt;SSTORE&lt;&#x2F;code&gt; metering and &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; to ensure &quot;de-facto storage loads&quot; inherent in those opcodes are priced correctly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Generally, the main function of gas costs of opcodes is to be an estimate of the time needed to process that opcode, the goal being for the gas limit to correspond to a limit on the time needed to process a block. However, storage-accessing opcodes (&lt;code&gt;SLOAD&lt;&#x2F;code&gt;, as well as the &lt;code&gt;*CALL&lt;&#x2F;code&gt;, &lt;code&gt;BALANCE&lt;&#x2F;code&gt; and &lt;code&gt;EXT*&lt;&#x2F;code&gt; opcodes) have historically been underpriced. In the 2016 Shanghai DoS attacks, once the most serious client bugs were fixed, one of the more durably successful strategies used by the attacker was to simply send transactions that access or call a large number of accounts.&lt;&#x2F;p&gt;
&lt;p&gt;Gas costs were increased to mitigate this, but recent numbers suggest they were not increased enough. Quoting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1909.07220.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1909.07220.pdf&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Although by itself, this issue might seem benign, &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; forces the  client to search the contract ondisk, resulting in IO heavy transactions.  While replaying the Ethereum history on our hardware, the malicious transactions took around 20 to 80 seconds to execute, compared to a few milliseconds for the average transactions&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This proposed EIP increases the costs of these opcodes by a factor of ~3, reducing the worst-case processing time to ~7-27 seconds. Improvements in database layout that involve redesigning the client to read storage directly instead of hopping through the Merkle tree would decrease this further, though these technologies may take a long time to fully roll out, and even with such technologies the IO overhead of accessing storage would remain substantial.&lt;&#x2F;p&gt;
&lt;p&gt;A secondary benefit of this EIP is that it also performs most of the work needed to make &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;protocol-changes-to-bound-witness-size&#x2F;3885&quot;&gt;stateless witness sizes&lt;&#x2F;a&gt; in Ethereum acceptable. Assuming &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;binary-trie-format&#x2F;7621&quot;&gt;a switch to binary tries&lt;&#x2F;a&gt;, the theoretical maximum witness size not including code size (hence &quot;most of the work&quot; and not &quot;all&quot;) would decrease from &lt;code&gt;(12500000 gas limit) &#x2F; (700 gas per BALANCE) * (800 witness bytes per BALANCE) ~= 14.3M bytes&lt;&#x2F;code&gt; to &lt;code&gt;12500000 &#x2F; 2600 * 800 ~= 3.85M bytes&lt;&#x2F;code&gt;. Pricing for code access could be changed when code merklization is implemented.&lt;&#x2F;p&gt;
&lt;p&gt;In the further future, there are similar benefits in the case of SNARK&#x2F;STARK witnesses. Recent numbers from Starkware suggest that they are able to prove 10000 Rescue hashes per second on a consumer desktop; assuming 25 hashes per Merkle branch, and a block full of state accesses, at present this would imply a witness would take &lt;code&gt;12500000 &#x2F; 700 * 25 &#x2F; 10000 ~= 44.64&lt;&#x2F;code&gt; seconds to generate, but after this EIP that would reduce to &lt;code&gt;12500000 &#x2F; 2500 * 25 &#x2F; 10000 ~= 12.5&lt;&#x2F;code&gt; seconds, meaning that a single desktop computer would be able to generate witnesses on time under any conditions. Future gains in STARK proving could be spent on either (i) using a more expensive but robust hash function or (ii) reducing proving times further, reducing the delay and hence improving user experience of stateless clients that rely on such witnesses.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;12244000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;COLD_SLOAD_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2100&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;COLD_ACCOUNT_ACCESS_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2600&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;WARM_STORAGE_READ_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;For blocks where &lt;code&gt;block.number &amp;gt;= FORK_BLOCK&lt;&#x2F;code&gt;, the following changes apply.&lt;&#x2F;p&gt;
&lt;p&gt;When executing a transaction, maintain a set &lt;code&gt;accessed_addresses: Set[Address]&lt;&#x2F;code&gt; and &lt;code&gt;accessed_storage_keys: Set[Tuple[Address, Bytes32]]&lt;&#x2F;code&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;The sets are transaction-context-wide, implemented identically to other transaction-scoped constructs such as the self-destruct-list and global &lt;code&gt;refund&lt;&#x2F;code&gt; counter. In particular, if a scope reverts, the access lists should be in the state they were in before that scope was entered.&lt;&#x2F;p&gt;
&lt;p&gt;When a transaction execution begins,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt; is initialized to empty, and&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; is initialized to include
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;tx.sender&lt;&#x2F;code&gt;, &lt;code&gt;tx.to&lt;&#x2F;code&gt; (or the address being created if it is a contract creation transaction)&lt;&#x2F;li&gt;
&lt;li&gt;and the set of all precompiles.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;storage-read-changes&quot;&gt;Storage read changes&lt;&#x2F;h3&gt;
&lt;p&gt;When an address is either the target of a (&lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; (&lt;code&gt;0x3B&lt;&#x2F;code&gt;), &lt;code&gt;EXTCODECOPY&lt;&#x2F;code&gt; (&lt;code&gt;0x3C&lt;&#x2F;code&gt;), &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; (&lt;code&gt;0x3F&lt;&#x2F;code&gt;) or &lt;code&gt;BALANCE&lt;&#x2F;code&gt; (&lt;code&gt;0x31&lt;&#x2F;code&gt;)) opcode or the target of a (&lt;code&gt;CALL&lt;&#x2F;code&gt; (&lt;code&gt;0xF1&lt;&#x2F;code&gt;), &lt;code&gt;CALLCODE&lt;&#x2F;code&gt; (&lt;code&gt;0xF2&lt;&#x2F;code&gt;), &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; (&lt;code&gt;0xF4&lt;&#x2F;code&gt;), &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; (&lt;code&gt;0xFA&lt;&#x2F;code&gt;)) opcode, the gas costs are computed as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the target is not in &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;, charge &lt;code&gt;COLD_ACCOUNT_ACCESS_COST&lt;&#x2F;code&gt; gas, and add the address to &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, charge &lt;code&gt;WARM_STORAGE_READ_COST&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In all cases, the gas cost is charged and the map is updated at the time that the opcode is being called.
When a &lt;code&gt;CREATE&lt;&#x2F;code&gt; or &lt;code&gt;CREATE2&lt;&#x2F;code&gt; opcode is called, immediately (ie. before checks are done to determine whether or not the address is unclaimed) add the address being created to &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt;, but gas costs of &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; are unchanged.
Clarification: If a &lt;code&gt;CREATE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;CREATE2&lt;&#x2F;code&gt; operation fails later on, e.g during the execution of &lt;code&gt;initcode&lt;&#x2F;code&gt; or has insufficient gas to store the code in the state, the &lt;code&gt;address&lt;&#x2F;code&gt; of the contract itself remains in &lt;code&gt;access_addresses&lt;&#x2F;code&gt; (but any additions made within the inner scope are reverted).&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, if the &lt;code&gt;(address, storage_key)&lt;&#x2F;code&gt; pair (where &lt;code&gt;address&lt;&#x2F;code&gt; is the address of the contract whose storage is being read) is not yet in &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt;, charge &lt;code&gt;COLD_SLOAD_COST&lt;&#x2F;code&gt; gas and add the pair to &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt;. If the pair is already in &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt;, charge &lt;code&gt;WARM_STORAGE_READ_COST&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;p&gt;Note: For call-variants, the &lt;code&gt;100&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;2600&lt;&#x2F;code&gt; cost is applied immediately (exactly like how &lt;code&gt;700&lt;&#x2F;code&gt; was charged before this EIP), i.e: before calculating the &lt;code&gt;63&#x2F;64ths&lt;&#x2F;code&gt; available for entering the call.&lt;&#x2F;p&gt;
&lt;p&gt;Note 2: There is currently no way to perform a &#x27;cold sload read&#x2F;write&#x27; on a &#x27;cold account&#x27;, simply because in order to read&#x2F;write a &lt;code&gt;slot&lt;&#x2F;code&gt;, the execution must already be inside the &lt;code&gt;account&lt;&#x2F;code&gt;. Therefore, the behaviour of cold  storage reads&#x2F;writes on cold accounts is undefined as of this EIP. Any future EIP which
proposes to add &#x27;remote read&#x2F;write&#x27; would need to define the pricing behaviour of that change.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sstore-changes&quot;&gt;SSTORE changes&lt;&#x2F;h3&gt;
&lt;p&gt;When calling &lt;code&gt;SSTORE&lt;&#x2F;code&gt;, check if the &lt;code&gt;(address, storage_key)&lt;&#x2F;code&gt; pair is in &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt;. If it is not, charge an additional &lt;code&gt;COLD_SLOAD_COST&lt;&#x2F;code&gt; gas, and add the pair to &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt;. Additionally, modify the parameters defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt; as follows:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;Old value&lt;&#x2F;th&gt;&lt;th&gt;New value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;800&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;= WARM_STORAGE_READ_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SSTORE_RESET_GAS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5000&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;5000 - COLD_SLOAD_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The other parameters defined in EIP 2200 are unchanged.
Note: The constant &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt; is used in several places in EIP 2200, e.g &lt;code&gt;SSTORE_SET_GAS - SLOAD_GAS&lt;&#x2F;code&gt;. Implementations that are using composite definitions have to ensure to update those definitions too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;selfdestruct-changes&quot;&gt;SELFDESTRUCT changes&lt;&#x2F;h3&gt;
&lt;p&gt;If the ETH recipient of a &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is not in &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; (regardless of whether or not the amount sent is nonzero), charge an additional &lt;code&gt;COLD_ACCOUNT_ACCESS_COST&lt;&#x2F;code&gt; on top of the existing gas costs, and add the ETH recipient to the set.&lt;&#x2F;p&gt;
&lt;p&gt;Note: &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; does not charge a &lt;code&gt;WARM_STORAGE_READ_COST&lt;&#x2F;code&gt; in case the recipient is already warm, which differs from how the other call-variants work. The reasoning behind this is to keep the changes small, a &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; already costs &lt;code&gt;5K&lt;&#x2F;code&gt; and is a no-op if invoked more than once.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;opcode-costs-vs-charging-per-byte-of-witness-data&quot;&gt;Opcode costs vs charging per byte of witness data&lt;&#x2F;h3&gt;
&lt;p&gt;The natural alternative path to changing gas costs to reflect witness sizes is to charge per byte of witness data. However, that would take a longer time to implement, hampering the goal of providing short-term security relief. Furthermore, following that path faithfully would lead to extremely high gas costs to transactions that touch contract code, as one would need to charge for all 24576 contract code bytes; this would be an unacceptably high burden on developers. It is better to wait for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;ewasm&#x2F;evm-bytecode-merklization-2a8366ab0c90&quot;&gt;code merklization&lt;&#x2F;a&gt; to start trying to properly account for gas costs of accessing individual chunks of code; from a short-term DoS prevention standpoint, accessing 24 kB from disk is not much more expensive than accessing 32 bytes from disk, so worrying about code size is not necessary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adding-the-accessed-addresses-accessed-storage-keys-sets&quot;&gt;Adding the accessed_addresses &#x2F; accessed_storage_keys sets&lt;&#x2F;h3&gt;
&lt;p&gt;The sets of already-accessed accounts and storage slots are added to avoid needlessly charging for things that can be cached (and in all performant implementations already are cached). Additionally, it removes the current undesirable status quo where it is needlessly unaffordable to do self-calls or call precompiles, and enables contract breakage mitigations that involve pre-fetching some storage key allowing a future execution to still take the expected amount of gas.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sstore-gas-cost-change&quot;&gt;SSTORE gas cost change&lt;&#x2F;h3&gt;
&lt;p&gt;The change to SSTORE is needed to avoid the possibility of a DoS attack that &quot;pokes&quot; a randomly chosen zero storage slot, changing it from 0 to 0 at a cost of 800 gas but requiring a de-facto storage load. The &lt;code&gt;SSTORE_RESET_GAS&lt;&#x2F;code&gt; reduction ensures that the total cost of SSTORE (which now requires paying the &lt;code&gt;COLD_SLOAD_COST&lt;&#x2F;code&gt;) remains unchanged. Additionally, note that applications that do &lt;code&gt;SLOAD&lt;&#x2F;code&gt; followed by &lt;code&gt;SSTORE&lt;&#x2F;code&gt; (eg. &lt;code&gt;storage_variable += x&lt;&#x2F;code&gt;) &lt;em&gt;would actually get cheaper&lt;&#x2F;em&gt;!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;change-sstore-accounting-only-minimally&quot;&gt;Change SSTORE accounting only minimally&lt;&#x2F;h3&gt;
&lt;p&gt;The SSTORE gas costs continue to use Wei Tang&#x27;s original&#x2F;current&#x2F;new approach, instead of being redesigned to use a dirty map, because Wei Tang&#x27;s approach correctly accounts for the actual costs of changing storage, which only care about current vs final value and not intermediate values.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-would-gas-consumption-of-average-applications-increase-under-this-proposal&quot;&gt;How would gas consumption of average applications increase under this proposal?&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;rough-analysis-from-witness-sizes&quot;&gt;Rough analysis from witness sizes&lt;&#x2F;h4&gt;
&lt;p&gt;We can look at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@akhounov&#x2F;data-from-the-ethereum-stateless-prototype-8c69479c8abc&quot;&gt;Alexey Akhunov&#x27;s earlier work&lt;&#x2F;a&gt; for data on average-case blocks. In summary, average blocks have witness sizes of ~1000 kB, of which ~750 kB is Merkle proofs and not code. Assuming a conservative 2000 bytes per Merkle branch this implies ~375 accesses per block (SLOADs have a similar gas-increase-to-bytes ratio so there&#x27;s no need to analyze them separately).&lt;&#x2F;p&gt;
&lt;p&gt;Data on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;etherscan.io&#x2F;chart&#x2F;tx&quot;&gt;txs per day&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;etherscan.io&#x2F;chart&#x2F;blocks&quot;&gt;blocks per day&lt;&#x2F;a&gt; from Etherscan gives ~160 transactions per block (reference date: Jul 1), implying a large portion of those accesses are just the &lt;code&gt;tx.sender&lt;&#x2F;code&gt; and &lt;code&gt;tx.to&lt;&#x2F;code&gt; which are excluded from gas cost increases, though likely less than 320 due to duplicate addresses.&lt;&#x2F;p&gt;
&lt;p&gt;Hence, this implies ~50-375 chargeable accesses per block, and each access suffers a gas cost increase of 1900; &lt;code&gt;50 * 1900 = 95000&lt;&#x2F;code&gt; and &lt;code&gt;375 * 1900 = 712500&lt;&#x2F;code&gt;, implying the gas limit would need to be raised by ~1-6% to compensate. However, this analysis may be complicated further in either direction by (i) accounts &#x2F; storage keys being accessed in multiple transactions, which would appear once in the witness but twice in gas cost increases, and (ii) accounts &#x2F; storage keys being accessed multiple times in the same transaction, which lead to gas cost &lt;em&gt;decreases&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;goerli-analysis&quot;&gt;Goerli analysis&lt;&#x2F;h4&gt;
&lt;p&gt;A more precise analysis can be found by scanning Goerli transactions, as done by Martin Swende here: https:&#x2F;&#x2F;github.com&#x2F;holiman&#x2F;gasreprice&lt;&#x2F;p&gt;
&lt;p&gt;The conclusion is that on average gas costs increase by ~2.36%. One major contributing factor to reducing gas costs is that a large number of contracts inefficiently read the same storage slot multiple times, which leads to this EIP giving a few transactions gas cost &lt;em&gt;savings&lt;&#x2F;em&gt; of over 10%.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;These gas cost increases may potentially break contracts that depend on fixed gas costs; see the security considerations section for details and arguments for why we expect the total risks to be low and how if desired they can be reduced further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Some test cases can be found here: https:&#x2F;&#x2F;gist.github.com&#x2F;holiman&#x2F;174548cad102096858583c6fbbb0649a&lt;&#x2F;p&gt;
&lt;p&gt;Ideally we would test the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SLOAD the same storage slot {1, 2, 3} times&lt;&#x2F;li&gt;
&lt;li&gt;CALL the same address {1, 2, 3} times&lt;&#x2F;li&gt;
&lt;li&gt;(SLOAD | CALL) in a sub-call, then revert, then (SLOAD | CALL) the same (storage slot | address) again&lt;&#x2F;li&gt;
&lt;li&gt;Sub-call, SLOAD, sub-call again, revert the inner sub-call, SLOAD the same storage slot&lt;&#x2F;li&gt;
&lt;li&gt;SSTORE the same storage slot {1, 2, 3} times, using all combinations of zero&#x2F;nonzero for original value and the value being set&lt;&#x2F;li&gt;
&lt;li&gt;SSTORE then SLOAD the same storage slot&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;OP_1&lt;&#x2F;code&gt; then &lt;code&gt;OP_2&lt;&#x2F;code&gt; to the same address where &lt;code&gt;OP_1&lt;&#x2F;code&gt; and &lt;code&gt;OP_2&lt;&#x2F;code&gt; are all combinations of (&lt;code&gt;*CALL&lt;&#x2F;code&gt;, &lt;code&gt;EXT*&lt;&#x2F;code&gt;, &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Try to &lt;code&gt;CALL&lt;&#x2F;code&gt; an address but with all possible failure modes (not enough gas, not enough ETH...), then (&lt;code&gt;CALL&lt;&#x2F;code&gt; | &lt;code&gt;EXT*&lt;&#x2F;code&gt;) that address again successfully&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A WIP early-draft implementation for Geth can be found here: https:&#x2F;&#x2F;github.com&#x2F;holiman&#x2F;go-ethereum&#x2F;tree&#x2F;access_lists&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;As with any gas cost increasing EIP, there are three possible cases where it could cause applications to break:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Fixed gas limits to sub-calls in contracts&lt;&#x2F;li&gt;
&lt;li&gt;Applications relying on contract calls that consume close to the full gas limit&lt;&#x2F;li&gt;
&lt;li&gt;The 2300 base limit given to the callee by ETH-transferring calls&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;These risks have been studied before in the context of an earlier gas cost increase, EIP-1884. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;holiman&#x2F;eip-1884-security&quot;&gt;Martin Swende&#x27;s earlier report&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;ritzdorf&#x2F;1c6bd72955391e831f8a397d3152b4e0&#x2F;&quot;&gt;Hubert Ritzdorf&#x27;s analysis&lt;&#x2F;a&gt; focusing on (1) and (3). (2) has received less analysis, though one can argue that it is very unlikely both because applications tend to very rarely use close to the entire gas limit in a transaction, and because gas limits were very recently raised from 10 million to 12.5 million. EIP-1884 in practice &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coindesk.com&#x2F;ethereums-istanbul-upgrade-will-break-680-smart-contracts-on-aragon&quot;&gt;did lead to a small number of contracts breaking&lt;&#x2F;a&gt; for this reason.&lt;&#x2F;p&gt;
&lt;p&gt;There are two ways to look at these risks. First, we can note that as of today developers have had years of warning; gas cost increases on storage-accessing opcodes have been &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;protocol-changes-to-bound-witness-size&#x2F;3885&quot;&gt;discussed for a long time&lt;&#x2F;a&gt;, with multiple statements made including to major dapp developers around the likelihood of such changes. EIP-1884 itself provided an important wake-up call. Hence, we can argue that risks this time will be significantly lower than EIP-1884.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-breakage-mitigations&quot;&gt;Contract breakage mitigations&lt;&#x2F;h3&gt;
&lt;p&gt;A second way to look at the risks is to explore mitigations. First of all, the existence of an &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; and &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt; map (present in this EIP, absent in EIP-1884) already makes some cases recoverable: in any case where a contract A needs to send funds to some address B, where that address accepts funds from any source but leaves a storage-dependent log, one can recover by first sending a separate call to B to pull it into the cache, and then call A, knowing that the execution of B triggered by A will only charge 100 gas per SLOAD. This fact does not fix all situations, but it does reduce risks significantly.&lt;&#x2F;p&gt;
&lt;p&gt;But there are ways to further expand the usability of this pattern. One possibility is to add a &lt;code&gt;POKE&lt;&#x2F;code&gt; precompile, which would take an address and a storage key as input and allow transactions that attempt to &quot;rescue&quot; stuck contracts by pre-poking all of the storage slots that they will access. This works even if the address only accepts transactions from the contract, and works in many other contexts with present gas limits. The only case where this will not work would be the case where a transaction call &lt;em&gt;must&lt;&#x2F;em&gt; go from an EOA straight into a specific contract that then sub-calls another contract.&lt;&#x2F;p&gt;
&lt;p&gt;Another option is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2930&#x2F;&quot;&gt;EIP-2930&lt;&#x2F;a&gt;, which would have a similar effect to &lt;code&gt;POKE&lt;&#x2F;code&gt; but is more general: it also works for the EOA -&amp;gt; contract -&amp;gt; contract case, and generally should work for all known cases of breakage due to gas cost increases. This option is more complex, though it is arguably a stepping stone toward access lists being used for other use cases (regenesis, account abstraction, SSA all demand access lists).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Optional access lists</title>
        <published>2020-08-29T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Martin Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2930/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2930-optional-access-lists/4561" />
        

        <id>https://wg-eips.ritovision.com/2930/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2930"
            label="EIP-2930" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2930/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Adds a transaction type which contains an access list, a list of addresses and storage keys that the transaction plans to access. Accesses outside the list are possible, but become more expensive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;We introduce a new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction type, with the format &lt;code&gt;0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;accessList&lt;&#x2F;code&gt; specifies a list of addresses and storage keys; these addresses and storage keys are added into the &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; and &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt; global sets (introduced in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt;). A gas cost is charged, though at a discount relative to the cost of accessing outside the list.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP serves two functions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Mitigates contract breakage risks introduced by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2929&#x2F;&quot;&gt;EIP-2929&lt;&#x2F;a&gt;, as transactions could pre-specify and pre-pay for the accounts and storage slots that the transaction plans to access; as a result, in the actual execution, the SLOAD and EXT* opcodes would only cost 100 gas: low enough that it would not only prevent breakage due to that EIP but also &quot;unstuck&quot; any contracts that became stuck due to EIP 1884.&lt;&#x2F;li&gt;
&lt;li&gt;Introduces the access list format and the logic for handling the format. This logic can later be repurposed for many other purposes, including block-wide witnesses, use in ReGenesis, moving toward static state access over time, and more.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;TransactionType&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; &lt;code&gt;1&lt;&#x2F;code&gt;.  See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ChainId&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The transaction only valid on networks with this &lt;code&gt;chainID&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;YParity&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; The parity (0 for even, 1 for odd) of the y-value of a secp256k1 signature.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Constant&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FORK_BLOCK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;12244000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1900&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ACCESS_LIST_ADDRESS_COST&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2400&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;As of &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt;, a new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction is introduced with &lt;code&gt;TransactionType&lt;&#x2F;code&gt; &lt;code&gt;1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; for this transaction is &lt;code&gt;rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;signatureYParity, signatureR, signatureS&lt;&#x2F;code&gt; elements of this transaction represent a secp256k1 signature over &lt;code&gt;keccak256(0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList]))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; for this transaction is &lt;code&gt;rlp([status, cumulativeGasUsed, logsBloom, logs])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For the transaction to be valid, &lt;code&gt;accessList&lt;&#x2F;code&gt; must be of type &lt;code&gt;[[{20 bytes}, [{32 bytes}...]]...]&lt;&#x2F;code&gt;, where &lt;code&gt;...&lt;&#x2F;code&gt; means &quot;zero or more of the thing to the left&quot;. For example, the following is a valid access list (all hex strings would in reality be in byte representation):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae&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;            &amp;quot;0x0000000000000000000000000000000000000000000000000000000000000003&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;0x0000000000000000000000000000000000000000000000000000000000000007&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;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;        &amp;quot;0xbb9bc244d798123fde783fcc1c72d3bb8c189413&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;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;At the beginning of execution (ie. at the same time as the &lt;code&gt;21000 + 4 * zeroes + 16 * nonzeroes&lt;&#x2F;code&gt; start gas is charged according to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2028&#x2F;&quot;&gt;EIP-2028&lt;&#x2F;a&gt; rules), we charge additional gas for the access list: &lt;code&gt;ACCESS_LIST_ADDRESS_COST&lt;&#x2F;code&gt; gas per address and &lt;code&gt;ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;code&gt; gas per storage key. For example, the above example would be charged &lt;code&gt;ACCESS_LIST_ADDRESS_COST * 2 + ACCESS_LIST_STORAGE_KEY_COST * 2&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;p&gt;Note that non-unique addresses and storage keys are not disallowed, though they will be charged for multiple times, and aside from the higher gas cost there is no other difference in execution flow or outcome from multiple-inclusion of a value as opposed to the recommended single-inclusion.&lt;&#x2F;p&gt;
&lt;p&gt;The address and storage keys would be immediately loaded into the &lt;code&gt;accessed_addresses&lt;&#x2F;code&gt; and &lt;code&gt;accessed_storage_keys&lt;&#x2F;code&gt; global sets; this can be done using the following logic (which doubles as a specification-in-code of validation of the RLP-decoded access list)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; process_access_list&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;access_list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Pair&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Bytes32&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&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&gt;    accessed_addresses&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; set&lt;&#x2F;span&gt;&lt;span&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&gt;    accessed_storage_keys&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; set&lt;&#x2F;span&gt;&lt;span&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&gt;    gas_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;access_list&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; access_list&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Validate and add the address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        accessed_addresses&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        gas_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ACCESS_LIST_ADDRESS_COST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Validate and add the storage keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            accessed_storage_keys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span&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&gt;            gas_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ACCESS_LIST_STORAGE_KEY_COST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        accessed_addresses&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        accessed_storage_keys&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gas_cost&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 access list is NOT charged per-byte fees like tx data is; the per-item costs described above are meant to cover the bandwidth costs of the access list data in addition to the costs of accessing those accounts and storage keys when evaluating the transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;charging-less-for-accesses-in-the-access-list&quot;&gt;Charging less for accesses in the access list&lt;&#x2F;h3&gt;
&lt;p&gt;This is done to encourage transactions to use the access list as much as possible, and because processing transactions is easier when their storage reads are predictable (because clients can pre-load the data from databases and&#x2F;or ask for witnesses at the time the transaction is received, or at least load the data in parallel).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;allowing-duplicates&quot;&gt;Allowing duplicates&lt;&#x2F;h3&gt;
&lt;p&gt;This is done because it maximizes simplicity, avoiding questions of what to prevent duplication against: just between two addresses&#x2F;keys in the access list, between the access list and the tx sender&#x2F;recipient&#x2F;newly created contract, other restrictions? Because gas is charged per item, there is no gain and only cost in including a value in the access list twice, so this should not lead to extra chain bloat in practice.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;signature-signs-over-the-transaction-type-as-well-as-the-transaction-data&quot;&gt;Signature signs over the transaction type as well as the transaction data&lt;&#x2F;h3&gt;
&lt;p&gt;This is done to ensure that the transaction cannot be &quot;re-interpreted&quot; as a transaction of a different type.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does make it more gas-expensive to perform &quot;unexpected&quot; SLOADs and account accesses. Because gas is prepaid and so does not affect fixed-gas local calls, it does not break contracts in the way that previous gas cost increases would risk. However, it does make applications that heavily rely on storage access much less economically viable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;access-list-generation&quot;&gt;Access list generation&lt;&#x2F;h3&gt;
&lt;p&gt;Access lists are difficult to construct in real-time in many situations, and this is exacerbated in environments where there is a high time lag between transaction generation and signing or simplicity of the transaction generator is highly valued (eg. either or both may apply in hardware wallets).&lt;&#x2F;p&gt;
&lt;p&gt;However, this EIP proposes only a 10% initial discount to access lists, so there is almost no cost to not bothering with access list generation and only making a simple transaction. The cost of accessing state outside the access list is expected to be ramped up in future hard forks over time as tools are developed and access list generation becomes more mature.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transaction-size-bloating&quot;&gt;Transaction size bloating&lt;&#x2F;h3&gt;
&lt;p&gt;Average block size will increase as a result of access lists being used. However, the per-byte cost of access lists is &lt;code&gt;1900 &#x2F; 32 = 59.375&lt;&#x2F;code&gt; for storage keys and &lt;code&gt;2400 &#x2F; 20 = 120&lt;&#x2F;code&gt; for addresses, making it much more expensive than calldata; hence, worst-case block size will not increase. Additionally, increases in average block size will be partially compensated for by the ability to pre-fetch storage at time of receiving a transaction and&#x2F;or load storage in parallel upon receiving a block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>CCIP Read—Secure offchain data retrieval</title>
        <published>2020-07-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><uri>https://github.com/arachnid</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/3668/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/durin-secure-offchain-data-retrieval/6728" />
        

        <id>https://wg-eips.ritovision.com/3668/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:3668"
            label="ERC-3668" />
        

        
        

        
        <summary type="html">CCIP Read provides a mechanism to allow a contract to fetch external data.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/3668/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Contracts wishing to support lookup of data from external sources may, instead of returning the data directly, revert using &lt;code&gt;OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData)&lt;&#x2F;code&gt;. Clients supporting this specification then make an RPC call to a URL from &lt;code&gt;urls&lt;&#x2F;code&gt;, supplying &lt;code&gt;callData&lt;&#x2F;code&gt;, and getting back an opaque byte string &lt;code&gt;response&lt;&#x2F;code&gt;. Finally, clients call the function specified by &lt;code&gt;callbackFunction&lt;&#x2F;code&gt; on the contract, providing &lt;code&gt;response&lt;&#x2F;code&gt; and &lt;code&gt;extraData&lt;&#x2F;code&gt;. The contract can then decode and verify the returned data using an implementation-specific method.&lt;&#x2F;p&gt;
&lt;p&gt;This mechanism allows for offchain lookups of data in a way that is transparent to clients, and allows contract authors to implement whatever validation is necessary; in many cases this can be provided without any additional trust assumptions over and above those required if data is stored onchain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Minimising storage and transaction costs on Ethereum has driven contract authors to adopt a variety of techniques for moving data offchain, including hashing, recursive hashing (eg Merkle Trees&#x2F;Tries) and L2 solutions. While each solution has unique constraints and parameters, they all share in common the fact that enough information is stored onchain to validate the externally stored data when required.&lt;&#x2F;p&gt;
&lt;p&gt;Thus far, applications have tended to devise bespoke solutions rather than trying to define a universal standard. This is practical - although inefficient - when a single offchain data storage solution suffices, but rapidly becomes impractical in a system where multiple end-users may wish to make use of different data storage and availability solutions based on what suits their needs.&lt;&#x2F;p&gt;
&lt;p&gt;By defining a common specification allowing smart contract to fetch data from offchain, we facilitate writing clients that are entirely agnostic to the storage solution being used, which enables new applications that can operate without knowing about the underlying storage details of the contracts they interact with.&lt;&#x2F;p&gt;
&lt;p&gt;Examples of this include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Interacting with &#x27;airdrop&#x27; contracts that store a list of recipients offchain in a merkle trie.&lt;&#x2F;li&gt;
&lt;li&gt;Viewing token information for tokens stored on an L2 solution as if they were native L1 tokens.&lt;&#x2F;li&gt;
&lt;li&gt;Allowing delegation of data such as ENS domains to various L2 solutions, without requiring clients to support each solution individually.&lt;&#x2F;li&gt;
&lt;li&gt;Allowing contracts to proactively request external data to complete a call, without requiring the caller to be aware of the details of that data.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;Answering a query via CCIP read takes place in three steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Querying the contract.&lt;&#x2F;li&gt;
&lt;li&gt;Querying the gateway using the URL provided in (1).&lt;&#x2F;li&gt;
&lt;li&gt;Querying or sending a transaction to the contract using the data from (1) and (2).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In step 1, a standard blockchain call operation is made to the contract. The contract reverts with an error that specifies the data to complete the call can be found offchain, and provides the url to a service that can provide the answer, along with additional contextual information required for the call in step (3).&lt;&#x2F;p&gt;
&lt;p&gt;In step 2, the client calls the gateway service with the &lt;code&gt;callData&lt;&#x2F;code&gt; from the revert message in step (1). The gateway responds with an answer &lt;code&gt;response&lt;&#x2F;code&gt;, whose content is opaque to the client.&lt;&#x2F;p&gt;
&lt;p&gt;In step 3, the client calls the original contract, supplying the &lt;code&gt;response&lt;&#x2F;code&gt; from step (2) and the &lt;code&gt;extraData&lt;&#x2F;code&gt; returned by the contract in step (1). The contract decodes the provided data and uses it to validate the response and act on it - by returning information to the client or by making changes in a transaction. The contract could also revert with a new error to initiate another lookup, in which case the protocol starts again at step 1.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;│Client│                                          │Contract│ │Gateway @ url│&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ somefunc(...)                                    │             │&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ revert OffchainLookup(sender, urls, callData,    │             │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │                     callbackFunction, extraData) │             │&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ HTTP request (sender, callData)                  │             │&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ Response (result)                                │             │&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ callbackFunction(result, extraData)              │             │&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   │ answer                                           │             │&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;h3 id=&quot;contract-interface&quot;&gt;Contract interface&lt;&#x2F;h3&gt;
&lt;p&gt;A CCIP read enabled contract MUST revert with the following error whenever a function that requires offchain data is called:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OffchainLookup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; callData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; extraData&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;sender&lt;&#x2F;code&gt; is the address of the contract that raised the error, and is used to determine if the error was thrown by the contract the client called, or &#x27;bubbled up&#x27; from a nested call.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;urls&lt;&#x2F;code&gt; specifies a list of URL templates to services (known as gateways) that implement the CCIP read protocol and can formulate an answer to the query. &lt;code&gt;urls&lt;&#x2F;code&gt; can be the empty list &lt;code&gt;[]&lt;&#x2F;code&gt;, in which case the client MUST specify the URL template. The order in which URLs are tried is up to the client, but contracts SHOULD return them in order of priority, with the most important entry first.&lt;&#x2F;p&gt;
&lt;p&gt;Each URL may include two substitution parameters, &lt;code&gt;{sender}&lt;&#x2F;code&gt; and &lt;code&gt;{data}&lt;&#x2F;code&gt;. Before a call is made to the URL, &lt;code&gt;sender&lt;&#x2F;code&gt; is replaced with the lowercase 0x-prefixed hexadecimal formatted &lt;code&gt;sender&lt;&#x2F;code&gt; parameter, and &lt;code&gt;data&lt;&#x2F;code&gt; is replaced by the 0x-prefixed hexadecimal formatted &lt;code&gt;callData&lt;&#x2F;code&gt; parameter.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;callData&lt;&#x2F;code&gt; specifies the data to call the gateway with. This value is opaque to the client. Typically this will be ABI-encoded, but this is an implementation detail that contracts and gateways can standardise on as desired.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;callbackFunction&lt;&#x2F;code&gt; is the 4-byte function selector for a function on the original contract to which a callback should be sent.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;extraData&lt;&#x2F;code&gt; is additional data that is required by the callback, and MUST be retained by the client and provided unmodified to the callback function. This value is opaque to the client.&lt;&#x2F;p&gt;
&lt;p&gt;The contract MUST also implement a callback method for decoding and validating the data returned by the gateway. The name of this method is implementation-specific, but it MUST have the signature &lt;code&gt;(bytes response, bytes extraData)&lt;&#x2F;code&gt;, and MUST have the same return type as the function that reverted with &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the client successfully calls the gateway, the callback function specified in the &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; error will be invoked by the client, with &lt;code&gt;response&lt;&#x2F;code&gt; set to the value returned by the gateway, and &lt;code&gt;extraData&lt;&#x2F;code&gt; set to the value returned in the contract&#x27;s &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; error. The contract MAY initiate another CCIP read lookup in this callback, though authors should bear in mind that the limits on number of recursive invocations will vary from client to client.&lt;&#x2F;p&gt;
&lt;p&gt;In a call context (as opposed to a transaction), the return data from this call will be returned to the user as if it was returned by the function that was originally invoked.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example&lt;&#x2F;h4&gt;
&lt;p&gt;Suppose a contract has the following method:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;)&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;Data for these queries is stored offchain in some kind of hashed data structure, the details of which are not important for this example. The contract author wants the gateway to fetch the proof information for this query and call the following function with it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOfWithProof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; response&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; extraData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;)&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;One example of a valid implementation of &lt;code&gt;balanceOf&lt;&#x2F;code&gt; would thus be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OffchainLookup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&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&gt;        [&lt;&#x2F;span&gt;&lt;span&gt;url&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Gateway&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;getSignedBalance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&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&gt;        ContractName&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balanceOfWithProof&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that in this example the contract is returning &lt;code&gt;addr&lt;&#x2F;code&gt; in both &lt;code&gt;callData&lt;&#x2F;code&gt; and &lt;code&gt;extraData&lt;&#x2F;code&gt;, because it is required both by the gateway (in order to look up the data) and the callback function (in order to verify it). The contract cannot simply pass it to the gateway and rely on it being returned in the response, as this would give the gateway an opportunity to respond with an answer to a different query than the one that was initially issued.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;recursive-calls-in-ccip-aware-contracts&quot;&gt;Recursive calls in CCIP-aware contracts&lt;&#x2F;h4&gt;
&lt;p&gt;When a CCIP-aware contract wishes to make a call to another contract, and the possibility exists that the callee may implement CCIP read, the calling contract MUST catch all &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; errors thrown by the callee, and revert with a different error if the &lt;code&gt;sender&lt;&#x2F;code&gt; field of the error does not match the callee address.&lt;&#x2F;p&gt;
&lt;p&gt;The contract MAY choose to replace all &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; errors with a different error. Doing so avoids the complexity of implementing support for nested CCIP read calls, but renders them impossible.&lt;&#x2F;p&gt;
&lt;p&gt;Where the possibility exists that a callee implements CCIP read, a CCIP-aware contract MUST NOT allow the default solidity behaviour of bubbling up reverts from nested calls. This is to prevent the following situation:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Contract A calls non-CCIP-aware contract B.&lt;&#x2F;li&gt;
&lt;li&gt;Contract B calls back to A.&lt;&#x2F;li&gt;
&lt;li&gt;In the nested call, A reverts with &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Contract B does not understand CCIP read and propagates the &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; to its caller.&lt;&#x2F;li&gt;
&lt;li&gt;Contract A also propagates the &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; to its caller.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The result of this sequence of operations would be an &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; that looks valid to the client, as the &lt;code&gt;sender&lt;&#x2F;code&gt; field matches the address of the contract that was called, but does not execute correctly, as it only completes a nested invocation.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-1&quot;&gt;Example&lt;&#x2F;h4&gt;
&lt;p&gt;The code below demonstrates one way that a contract may support nested CCIP read invocations. For simplicity this is shown using Solidity&#x27;s try&#x2F;catch syntax, although as of this writing it does not yet support catching custom errors.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NestedLookup&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InvalidOperation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OffchainLookup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; callData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; extraData&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; target&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ret&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&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;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OffchainLookup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; callData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt; extraData&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InvalidOperation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OffchainLookup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&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&gt;                urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&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&gt;                NestedLookup&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;aCallback&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;                abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; extraData&lt;&#x2F;span&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;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;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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; aCallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; response&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; extraData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; inner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt; innerCallbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; innerExtraData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;extraData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;inner&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;innerCallbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; innerExtraData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;h3 id=&quot;gateway-interface&quot;&gt;Gateway Interface&lt;&#x2F;h3&gt;
&lt;p&gt;The URLs returned by a contract may be of any schema, but this specification only defines how clients should handle HTTPS URLs.&lt;&#x2F;p&gt;
&lt;p&gt;Given a URL template returned in an &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt;, the URL to query is composed by replacing  &lt;code&gt;sender&lt;&#x2F;code&gt; with the lowercase 0x-prefixed hexadecimal formatted &lt;code&gt;sender&lt;&#x2F;code&gt; parameter, and replacing &lt;code&gt;data&lt;&#x2F;code&gt; with the 0x-prefixed hexadecimal formatted &lt;code&gt;callData&lt;&#x2F;code&gt; parameter.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if a contract returns the following data in an &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;urls = [&amp;quot;https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;{sender}&#x2F;{data}.json&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sender = &amp;quot;0xaabbccddeeaabbccddeeaabbccddeeaabbccddee&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;callData = &amp;quot;0x00112233&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The request URL to query is &lt;code&gt;https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;0xaabbccddeeaabbccddeeaabbccddeeaabbccddee&#x2F;0x00112233.json&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the URL template contains the &lt;code&gt;{data}&lt;&#x2F;code&gt; substitution parameter, the client MUST send a GET request after replacing the substitution parameters as described above.&lt;&#x2F;p&gt;
&lt;p&gt;If the URL template does not contain the &lt;code&gt;{data}&lt;&#x2F;code&gt; substitution parameter, the client MUST send a POST request after replacing the substitution parameters as described above. The POST request MUST be sent with a Content-Type of &lt;code&gt;application&#x2F;json&lt;&#x2F;code&gt;, and a payload matching the following schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;    &amp;quot;type&amp;quot;: &amp;quot;object&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;quot;properties&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;data&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;description&amp;quot;: &amp;quot;0x-prefixed hex string containing the `callData` from the contract&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;        &amp;quot;sender&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;description&amp;quot;: &amp;quot;0x-prefixed hex string containing the `sender` parameter from the contract&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;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;Compliant gateways MUST respond with a Content-Type of &lt;code&gt;application&#x2F;json&lt;&#x2F;code&gt;, with the body adhering to the following JSON schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;    &amp;quot;type&amp;quot;: &amp;quot;object&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;quot;properties&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;data&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;description: &amp;quot;0x-prefixed hex string containing the result data.&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;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;Unsuccessful requests MUST return the appropriate HTTP status code - for example, 404 if the &lt;code&gt;sender&lt;&#x2F;code&gt; address is not supported by this gateway, 400 if the &lt;code&gt;callData&lt;&#x2F;code&gt; is in an invalid format, 500 if the server encountered an internal error, and so forth. If the Content-Type of a 4xx or 5xx response is &lt;code&gt;application&#x2F;json&lt;&#x2F;code&gt;, it MUST adhere to the following JSON schema:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;    &amp;quot;type&amp;quot;: &amp;quot;object&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;quot;properties&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;message&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &amp;quot;description: &amp;quot;A human-readable error message.&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;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;h4 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;GET request&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Client returned a URL template `https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;{sender}&#x2F;{data}.json`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Request&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;curl -D - https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8&#x2F;0xd5fa2b00.json&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;# Successful result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HTTP&#x2F;2 200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    content-type: application&#x2F;json; charset=UTF-8&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&amp;quot;data&amp;quot;: &amp;quot;0xdeadbeefdecafbad&amp;quot;}&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;# Error result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HTTP&#x2F;2 404&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    content-type: application&#x2F;json; charset=UTF-8&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&gt;    {&amp;quot;message&amp;quot;: &amp;quot;Gateway address not supported.&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;&lt;em&gt;&lt;strong&gt;POST request&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Client returned a URL template `https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;{sender}.json`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Request&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;curl -D - -X POST -H &amp;quot;Content-Type: application&#x2F;json&amp;quot; --data &amp;#39;{&amp;quot;data&amp;quot;:&amp;quot;0xd5fa2b00&amp;quot;,&amp;quot;sender&amp;quot;:&amp;quot;0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8&amp;quot;}&amp;#39; https:&#x2F;&#x2F;example.com&#x2F;gateway&#x2F;0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8.json&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;# Successful result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HTTP&#x2F;2 200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    content-type: application&#x2F;json; charset=UTF-8&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&amp;quot;data&amp;quot;: &amp;quot;0xdeadbeefdecafbad&amp;quot;}&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;# Error result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HTTP&#x2F;2 404&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    content-type: application&#x2F;json; charset=UTF-8&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&gt;    {&amp;quot;message&amp;quot;: &amp;quot;Gateway address not supported.&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;Clients MUST support both GET and POST requests. Gateways may implement either or both as needed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;client-lookup-protocol&quot;&gt;Client Lookup Protocol&lt;&#x2F;h3&gt;
&lt;p&gt;A client that supports CCIP read MUST make contract calls using the following process:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Set &lt;code&gt;data&lt;&#x2F;code&gt; to the call data to supply to the contract, and &lt;code&gt;to&lt;&#x2F;code&gt; to the address of the contract to call.&lt;&#x2F;li&gt;
&lt;li&gt;Call the contract at address &lt;code&gt;to&lt;&#x2F;code&gt; function normally, supplying &lt;code&gt;data&lt;&#x2F;code&gt; as the input data. If the function returns a successful result, return it to the caller and stop.&lt;&#x2F;li&gt;
&lt;li&gt;If the function returns an error other than &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt;, return it to the caller in the usual fashion.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, decode the &lt;code&gt;sender&lt;&#x2F;code&gt;, &lt;code&gt;urls&lt;&#x2F;code&gt;, &lt;code&gt;callData&lt;&#x2F;code&gt;, &lt;code&gt;callbackFunction&lt;&#x2F;code&gt; and &lt;code&gt;extraData&lt;&#x2F;code&gt; arguments from the &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; error.&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;sender&lt;&#x2F;code&gt; field does not match the address of the contract that was called, return an error to the caller and stop.&lt;&#x2F;li&gt;
&lt;li&gt;Construct a request URL by replacing &lt;code&gt;sender&lt;&#x2F;code&gt; with the lowercase 0x-prefixed hexadecimal formatted &lt;code&gt;sender&lt;&#x2F;code&gt; parameter, and replacing &lt;code&gt;data&lt;&#x2F;code&gt; with the 0x-prefixed hexadecimal formatted &lt;code&gt;callData&lt;&#x2F;code&gt; parameter. The client may choose which URLs to try in which order, but SHOULD prioritise URLs earlier in the list over those later in the list.&lt;&#x2F;li&gt;
&lt;li&gt;Make an HTTP GET request to the request URL.&lt;&#x2F;li&gt;
&lt;li&gt;If the response code from step (7) is in the range 400-499, return an error to the caller and stop.&lt;&#x2F;li&gt;
&lt;li&gt;If the response code from step (7) is in the range 500-599, go back to step (5) and pick a different URL, or stop if there are no further URLs to try.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, replace &lt;code&gt;data&lt;&#x2F;code&gt; with an ABI-encoded call to the contract function specified by the 4-byte selector &lt;code&gt;callbackFunction&lt;&#x2F;code&gt;, supplying the data returned from step (7) and &lt;code&gt;extraData&lt;&#x2F;code&gt; from step (4), and return to step (1).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Clients MUST handle HTTP status codes appropriately, employing best practices for error reporting and retries.&lt;&#x2F;p&gt;
&lt;p&gt;Clients MUST handle HTTP 4xx and 5xx error responses that have a content type other than application&#x2F;json appropriately; they MUST NOT attempt to parse the response body as JSON.&lt;&#x2F;p&gt;
&lt;p&gt;This protocol can result in multiple lookups being requested by the same contract. Clients MUST implement a limit on the number of lookups they permit for a single contract call, and this limit SHOULD be at least 4.&lt;&#x2F;p&gt;
&lt;p&gt;The lookup protocol for a client is described with the following pseudocode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; httpcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; callData&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toLowerCase&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; callData&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toLowerCase&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; of&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; urls&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; queryUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; url&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;g&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First argument is URL to fetch, second is optional data for a POST request.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; response&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; fetch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;queryUrl&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; url&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;includes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{data}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; response&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;text&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;result&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;statusCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 400&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;statusCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 499&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;result&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;statusCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;statusCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 299&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; result&lt;&#x2F;span&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; durin_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CALL_EXCEPTION&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                throw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&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&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; callData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; extraData&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;                throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Cannot handle OffchainLookup raised inside nested call&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; httpcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;urls&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; callData&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;            data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;callbackFunction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; extraData&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Too many CCIP read redirects&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;provider&lt;&#x2F;code&gt; is a provider object that facilitates Ethereum blockchain function calls.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;to&lt;&#x2F;code&gt; is the address of the contract to call.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;data&lt;&#x2F;code&gt; is the call data for the contract.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If the function being called is a standard contract function, the process terminates after the original call, returning the same result as for a regular call. Otherwise, a gateway from &lt;code&gt;urls&lt;&#x2F;code&gt; is called with the &lt;code&gt;callData&lt;&#x2F;code&gt; returned by the &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; error, and is expected to return a valid response. The response and the &lt;code&gt;extraData&lt;&#x2F;code&gt; are then passed to the specified callback function. This process can be repeated if the callback function returns another &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; error.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-of-ccip-read-for-transactions&quot;&gt;Use of CCIP read for transactions&lt;&#x2F;h3&gt;
&lt;p&gt;While the specification above is for read-only contract calls (eg, &lt;code&gt;eth_call&lt;&#x2F;code&gt;), it is simple to use this method for sending transactions (eg, &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt; or &lt;code&gt;eth_sendRawTransaction&lt;&#x2F;code&gt;) that require offchain data. While &#x27;preflighting&#x27; a transaction using &lt;code&gt;eth_estimateGas&lt;&#x2F;code&gt; or &lt;code&gt;eth_call&lt;&#x2F;code&gt;, a client that receives an &lt;code&gt;OffchainLookup&lt;&#x2F;code&gt; revert can follow the procedure described above in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3668&#x2F;#client-lookup-protocol&quot;&gt;Client lookup protocol&lt;&#x2F;a&gt;, substituting a transaction for the call in the last step. This functionality is ideal for applications such as making onchain claims supported by offchain proof data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;glossary&quot;&gt;Glossary&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Client: A process, such as JavaScript executing in a web browser, or a backend service, that wishes to query a blockchain for data. The client understands how to fetch data using CCIP read.&lt;&#x2F;li&gt;
&lt;li&gt;Contract: A smart contract existing on Ethereum or another blockchain.&lt;&#x2F;li&gt;
&lt;li&gt;Gateway: A service that answers application-specific CCIP read queries, usually over HTTPS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;use-of-revert-to-convey-call-information&quot;&gt;Use of &lt;code&gt;revert&lt;&#x2F;code&gt; to convey call information&lt;&#x2F;h3&gt;
&lt;p&gt;For offchain data lookup to function as desired, clients must either have some way to know that a function depends on this specification for functionality - such as a specifier in the ABI for the function - or else there must be a way for the contract to signal to the client that data needs to be fetched from elsewhere.&lt;&#x2F;p&gt;
&lt;p&gt;While specifying the call type in the ABI is a possible solution, this makes retrofitting existing interfaces to support offchain data awkward, and either results in contracts with the same name and arguments as the original specification, but with different return data - which will cause decoding errors for clients that do not expect this - or duplicating every function that needs support for offchain data with a different name (eg, &lt;code&gt;balanceOf -&amp;gt; offchainBalanceOf&lt;&#x2F;code&gt;). Neither solutions is particularly satisfactory.&lt;&#x2F;p&gt;
&lt;p&gt;Using a revert, and conveying the required information in the revert data, allows any function to be retrofitted to support lookups via CCIP read so long as the client understands the specification, and so facilitates translation of existing specifications to use offchain data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;passing-contract-address-to-the-gateway-service&quot;&gt;Passing contract address to the gateway service&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;address&lt;&#x2F;code&gt; is passed to the gateway in order to facilitate the writing of generic gateways, thus reducing the burden on contract authors to provide their own gateway implementations. Supplying &lt;code&gt;address&lt;&#x2F;code&gt; allows the gateway to perform lookups to the original contract for information needed to assist with resolution, making it possible to operate one gateway for any number of contracts implementing the same interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;existence-of-extradata-argument&quot;&gt;Existence of &lt;code&gt;extraData&lt;&#x2F;code&gt; argument&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;extraData&lt;&#x2F;code&gt; allows the original contract function to pass information to a subsequent invocation. Since contracts are not persistent, without this data a contract has no state from the previous invocation. Aside from allowing arbitrary contextual information to be propagated between the two calls, this also allows the contract to verify that the query the gateway answered is in fact the one the contract originally requested.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-of-get-and-post-requests-for-the-gateway-interface&quot;&gt;Use of GET and POST requests for the gateway interface&lt;&#x2F;h3&gt;
&lt;p&gt;Using a GET request, with query data encoded in the URL, minimises complexity and enables entirely static implementations of gateways - in some applications a gateway can simply be an HTTP server or IPFS instance with a static set of responses in text files.&lt;&#x2F;p&gt;
&lt;p&gt;However, URLs are limited to 2 kilobytes in size, which will impose issues for more complex uses of CCIP read. Thus, we provide for an option to use POST data. This is made at the contract&#x27;s discretion (via the choice of URL template) in order to preserve the ability to have a static gateway operating exclusively using GET when desired.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Existing contracts that do not wish to use this specification are unaffected. Clients can add support for CCIP read to all contract calls without introducing any new overhead or incompatibilities.&lt;&#x2F;p&gt;
&lt;p&gt;Contracts that require CCIP read will not function in conjunction with clients that do not implement this specification. Attempts to call these contracts from non-compliant clients will result in the contract throwing an exception that is propagaged to the user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gateway-response-data-validation&quot;&gt;Gateway Response Data Validation&lt;&#x2F;h3&gt;
&lt;p&gt;In order to prevent a malicious gateway from causing unintended side-effects or faulty results, contracts MUST include sufficient information in the &lt;code&gt;extraData&lt;&#x2F;code&gt; argument to allow them to verify the relevance and validity of the gateway&#x27;s response. For example, if the contract is requesting information based on an &lt;code&gt;address&lt;&#x2F;code&gt; supplied to the original call, it MUST include that address in the &lt;code&gt;extraData&lt;&#x2F;code&gt; so that the callback can verify the gateway is not providing the answer to a different query.&lt;&#x2F;p&gt;
&lt;p&gt;Contracts must also implement sufficient validation of the data returned by the gateway to ensure it is valid. The validation required is application-specific and cannot be specified on a global basis. Examples would include verifying a Merkle proof of inclusion for an L2 or other Merkleized state, or verifying a signature by a trusted signer over the response data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;client-extra-data-validation&quot;&gt;Client Extra Data Validation&lt;&#x2F;h3&gt;
&lt;p&gt;In order to prevent a malicious client from causing unintended effects when making transactions using CCIP read, contracts MUST implement appropriate checks on the &lt;code&gt;extraData&lt;&#x2F;code&gt; returned to them in the callback. Any sanity&#x2F;permission checks performed on input data for the initial call MUST be repeated on the data passed through the &lt;code&gt;extraData&lt;&#x2F;code&gt; field in the callback. For example, if a transaction should only be executable by an authorised account, that authorisation check MUST be done in the callback; it is not sufficient to perform it with the initial call and embed the authorised address in the &lt;code&gt;extraData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;http-requests-and-fingerprinting-attacks&quot;&gt;HTTP requests and fingerprinting attacks&lt;&#x2F;h3&gt;
&lt;p&gt;Because CCIP read can cause a user&#x27;s browser to make HTTP requests to an address controlled by the contract, there is the potential for this to be used to identify users - for example, to associate their wallet address with their IP address.&lt;&#x2F;p&gt;
&lt;p&gt;The impact of this is application-specific; fingerprinting a user when they resolve an ENS domain may have little privacy impact, as the attacker will not learn the user&#x27;s wallet address, only the fact that the user is resolving a given ENS name from a given IP address - information they can also learn from running a DNS server. On the other hand, fingerprinting a user when they attempt a transaction to transfer an NFT may give an attacker everything they need to identify the IP address of a user&#x27;s wallet.&lt;&#x2F;p&gt;
&lt;p&gt;To minimise the security impact of this, we make the following recommendations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Client libraries should provide clients with a hook to override CCIP read calls - either by rewriting them to use a proxy service, or by denying them entirely. This mechanism or another should be written so as to easily facilitate adding domains to allowlists or blocklists.&lt;&#x2F;li&gt;
&lt;li&gt;Client libraries should disable CCIP read for transactions (but not for calls) by default, and require the caller to explicitly enable this functionality. Enablement should be possible both on a per-contract, per-domain, or global basis.&lt;&#x2F;li&gt;
&lt;li&gt;App authors should not supply a &#x27;from&#x27; address for contract calls (&#x27;view&#x27; operations) where the call could execute untrusted code (that is, code not authored or trusted by the application author). As a precuationary principle it is safest to not supply this parameter at all unless the author is certain that no attacker-determined smart contract code will be executed.&lt;&#x2F;li&gt;
&lt;li&gt;Wallet authors that are responsible for fetching user information - for example, by querying token contracts - should either ensure CCIP read is disabled for transactions, and that no contract calls are made with a &#x27;from&#x27; address supplied, or operate a proxy on their users&#x27; behalf, rewriting all CCIP read calls to take place via the proxy, or both.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We encourage client library authors and wallet authors not to disable CCIP read by default, as many applications can be transparently enhanced with this functionality, which is quite safe if the above precautions are observed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Secure Protocol for Native Meta Transactions</title>
        <published>2020-07-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Ronan Sandford</name><uri>https://github.com/wighawag</uri>
	</author>
	
	<author>
		<name>Liraz Siri</name><uri>https://github.com/lirazsiri</uri>
	</author>
	
	<author>
		<name>Dror Tirosh</name><uri>https://github.com/drortirosh</uri>
	</author>
	
	<author>
		<name>Yoav Weiss</name><uri>https://github.com/yoavw</uri>
	</author>
	
	<author>
		<name>Alex Forshtat</name><uri>https://github.com/forshtat</uri>
	</author>
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	<author>
		<name>Sachin Tomar</name><uri>https://github.com/tomarsachin2271</uri>
	</author>
	
	<author>
		<name>Patrick McCorry</name><uri>https://github.com/stonecoldpat</uri>
	</author>
	
	<author>
		<name>Nicolas Venturo</name><uri>https://github.com/nventuro</uri>
	</author>
	
	<author>
		<name>Fabian Vogelsteller</name><uri>https://github.com/frozeman</uri>
	</author>
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2771/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-2771-secure-protocol-for-native-meta-transactions/4488" />
        

        <id>https://wg-eips.ritovision.com/2771/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:2771"
            label="ERC-2771" />
        

        
        

        
        <summary type="html">A contract interface for receiving meta transactions through a trusted forwarder</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2771/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a contract-level protocol for &lt;code&gt;Recipient&lt;&#x2F;code&gt; contracts to accept meta-transactions through trusted &lt;code&gt;Forwarder&lt;&#x2F;code&gt; contracts. No protocol changes are made. &lt;code&gt;Recipient&lt;&#x2F;code&gt; contracts are sent the effective &lt;code&gt;msg.sender&lt;&#x2F;code&gt; (referred to as &lt;code&gt;_msgSender()&lt;&#x2F;code&gt;) and &lt;code&gt;msg.data&lt;&#x2F;code&gt; (referred to as &lt;code&gt;_msgData()&lt;&#x2F;code&gt;) by appending additional calldata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There is a growing interest in making it possible for Ethereum contracts to accept calls from externally owned accounts that do not have ETH to pay for gas. Solutions that allow for third parties to pay for gas costs are called meta transactions. For the purposes of this EIP, meta transactions are transactions that have been authorized by a &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt; and relayed by an untrusted third party that pays for the gas (the &lt;strong&gt;Gas Relay&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt;: Signs &amp;amp; sends transactions to a Gas Relay&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Gas Relay&lt;&#x2F;strong&gt;: Receives signed requests off-chain from Transaction Signers and pays gas to turn it into a valid transaction that goes through a Trusted Forwarder&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Trusted Forwarder&lt;&#x2F;strong&gt;: A contract trusted by the &lt;code&gt;Recipient&lt;&#x2F;code&gt; to correctly verify signatures and nonces before forwarding the request from Transaction Signers&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Recipient&lt;&#x2F;strong&gt;: A contract that accepts meta-transactions through a Trusted Forwarder&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-flow&quot;&gt;Example Flow&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2771&#x2F;.&#x2F;assets&#x2F;example-flow.png&quot; alt=&quot;Example flow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extracting-the-transaction-signer-address&quot;&gt;Extracting The Transaction Signer address&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;strong&gt;Trusted Forwarder&lt;&#x2F;strong&gt; is responsible for calling the &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; contract and MUST append the address of the &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt; (20 bytes of data) to the end of the call data.&lt;&#x2F;p&gt;
&lt;p&gt;For example :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; returnData&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; from&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&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;strong&gt;Recipient&lt;&#x2F;strong&gt; contract can then extract the &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt; address by performing 3 operations:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Check that the &lt;strong&gt;Forwarder&lt;&#x2F;strong&gt; is trusted. How this is implemented is out of the scope of this proposal.&lt;&#x2F;li&gt;
&lt;li&gt;Extract the &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt; address from the last 20 bytes of the call data and use that as the original &lt;code&gt;sender&lt;&#x2F;code&gt; of the transaction (instead of &lt;code&gt;msg.sender&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is not a trusted forwarder (or if the &lt;code&gt;msg.data&lt;&#x2F;code&gt; is shorter than 20 bytes), then return the original &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as it is.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; MUST check that it trusts the Forwarder to prevent it from
extracting address data appended from an untrusted contract. This could result
in a forged address.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;protocol-support-discovery-mechanism&quot;&gt;Protocol Support Discovery Mechanism&lt;&#x2F;h3&gt;
&lt;p&gt;Unless a &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; contract is being used by a particular frontend that knows that this contract has support for native meta transactions, it would not be possible to offer the user the choice of using meta-transaction to interact with the contract. We thus need a mechanism by which the &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; can let the world know that it supports meta transactions.&lt;&#x2F;p&gt;
&lt;p&gt;This is especially important for meta transactions to be supported at the Web3 wallet level. Such wallets may not necessarily know anything about the &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; contract users may wish to interact with.&lt;&#x2F;p&gt;
&lt;p&gt;As a &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; could trust forwarders with different interfaces and capabilities (e.g., transaction batching, different message signing formats), we need to allow wallets to discover which Forwarder is trusted.&lt;&#x2F;p&gt;
&lt;p&gt;To provide this discovery mechanism a &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; contract MUST implement this function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTrustedForwarder&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; forwarder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&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;isTrustedForwarder&lt;&#x2F;code&gt; MUST return &lt;code&gt;true&lt;&#x2F;code&gt; if the forwarder is trusted by the Recipient, otherwise it MUST return &lt;code&gt;false&lt;&#x2F;code&gt;. &lt;code&gt;isTrustedForwarder&lt;&#x2F;code&gt; MUST NOT revert.&lt;&#x2F;p&gt;
&lt;p&gt;Internally, the &lt;strong&gt;Recipient&lt;&#x2F;strong&gt; MUST then accept a request from forwarder.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;isTrustedForwarder&lt;&#x2F;code&gt; function MAY be called on-chain, and as such gas restrictions MUST be put in place. It SHOULD NOT consume more than 50,000 gas&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Make it easy for contract developers to add support for meta
transactions by standardizing the simplest viable contract interface.&lt;&#x2F;li&gt;
&lt;li&gt;Without support for meta transactions in the recipient contract, an externally owned
account can not use meta transactions to interact with the recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;Without a standard contract interface, there is no standard way for a client
to discover whether a recipient supports meta transactions.&lt;&#x2F;li&gt;
&lt;li&gt;Without a standard contract interface, there is no standard way to send a
meta transaction to a recipient.&lt;&#x2F;li&gt;
&lt;li&gt;Without the ability to leverage a trusted forwarder every recipient contract
has to internally implement the logic required to accept meta transactions securely.&lt;&#x2F;li&gt;
&lt;li&gt;Without a discovery protocol, there is no mechanism for a client to discover
whether a recipient supports a specific forwarder.&lt;&#x2F;li&gt;
&lt;li&gt;Making the contract interface agnostic to the internal implementation
details of the trusted forwarder, makes it possible for a recipient contract
to support multiple forwarders with no change to code.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; is a transaction parameter that can be inspected by a contract to determine who signed the transaction. The integrity of this parameter is guaranteed by the Ethereum EVM, but for a meta transaction securing &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is insufficient.
&lt;ul&gt;
&lt;li&gt;The problem is that for a contract that is not natively aware of meta transactions, the &lt;code&gt;msg.sender&lt;&#x2F;code&gt; of the transaction will make it appear to be coming from the &lt;strong&gt;Gas Relay&lt;&#x2F;strong&gt; and not the &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt;. A secure protocol for a contract to accept meta transactions needs to prevent the &lt;strong&gt;Gas Relay&lt;&#x2F;strong&gt; from forging, modifying or duplicating requests by the &lt;strong&gt;Transaction Signer&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;recipient-example&quot;&gt;Recipient Example&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RecipientExample&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; purchaseItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; itemId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; sender &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ... perform the purchase for sender&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; immutable&lt;&#x2F;span&gt;&lt;span&gt; _trustedForwarder&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; trustedForwarder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        _trustedForwarder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; trustedForwarder&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTrustedForwarder&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; forwarder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; forwarder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; _trustedForwarder&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _msgSender&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signer&lt;&#x2F;span&gt;&lt;span&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&gt;        signer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isTrustedForwarder&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;                signer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; shr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;96&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;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;span class=&quot;giallo-l&quot;&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;A malicious forwarder may forge the value of &lt;code&gt;_msgSender()&lt;&#x2F;code&gt; and effectively send transactions from any address. Therefore, &lt;code&gt;Recipient&lt;&#x2F;code&gt; contracts must be very careful in trusting forwarders. If a forwarder is upgradeable, then one must also trust that the contract won&#x27;t perform a malicious upgrade.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, modifying which forwarders are trusted must be restricted, since an attacker could &quot;trust&quot; their own address to forward transactions, and therefore be able to forge transactions. It is recommended to have the list of trusted forwarders be immutable, and if this is not feasible, then only trusted contract owners should be able to modify it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Typed Transaction Envelope</title>
        <published>2020-06-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/MicahZoltu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2718/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2718-typed-transaction-envelope/4355" />
        

        <id>https://wg-eips.ritovision.com/2718/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:2718"
            label="EIP-2718" />
        

        
        

        
        <summary type="html">Defines a new transaction type that is an envelope for future transaction types.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2718/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;TransactionType || TransactionPayload&lt;&#x2F;code&gt; is a valid transaction and &lt;code&gt;TransactionType || ReceiptPayload&lt;&#x2F;code&gt; is a valid transaction receipt where &lt;code&gt;TransactionType&lt;&#x2F;code&gt; identifies the format of the transaction and &lt;code&gt;*Payload&lt;&#x2F;code&gt; is the transaction&#x2F;receipt contents, which are defined in future EIPs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;In the past, when we have wanted to add new transaction types we have had to ensure they were backward compatible with all other transactions, meaning that you could differentiate them based only on the encoded payload, and it was not possible to have a transaction that matched both types.
This was seen in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; where the new value was bit-packed into one of the encoded fields.
There are multiple proposals in discussion that define new transaction types such as one that allows EOA accounts to execute code directly within their context, one that enables someone besides &lt;code&gt;msg.sender&lt;&#x2F;code&gt; to pay for gas, and proposals related to layer 1 multi-sig transactions.
These all need to be defined in a way that is mutually compatible, which quickly becomes burdensome to EIP authors and to clients who now have to follow complex rules for differentiating transaction type.&lt;&#x2F;p&gt;
&lt;p&gt;By introducing an envelope transaction type, we only need to ensure backward compatibility with existing transactions and from then on we just need to solve the much simpler problem of ensuring there is no numbering conflict between &lt;code&gt;TransactionType&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;||&lt;&#x2F;code&gt; is the byte&#x2F;byte-array concatenation operator.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;transactions&quot;&gt;Transactions&lt;&#x2F;h3&gt;
&lt;p&gt;As of &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt;, the transaction root in the block header &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be the root hash of &lt;code&gt;patriciaTrie(rlp(Index) =&amp;gt; Transaction)&lt;&#x2F;code&gt; where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Index&lt;&#x2F;code&gt; is the index in the block of this transaction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Transaction&lt;&#x2F;code&gt; is either &lt;code&gt;TransactionType || TransactionPayload&lt;&#x2F;code&gt; or &lt;code&gt;LegacyTransaction&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionType&lt;&#x2F;code&gt; is a positive unsigned 8-bit number between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;0x7f&lt;&#x2F;code&gt; that represents the type of the transaction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; is an opaque byte array whose interpretation is dependent on the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; and defined in future EIPs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyTransaction&lt;&#x2F;code&gt; is &lt;code&gt;rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All signatures for future transaction types &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; include the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; as the first byte of the signed data.
This makes it so we do not have to worry about signatures for one transaction type being used as signatures for a different transaction type.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;receipts&quot;&gt;Receipts&lt;&#x2F;h3&gt;
&lt;p&gt;As of &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt;, the receipt root in the block header &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be the root hash of &lt;code&gt;patriciaTrie(rlp(Index) =&amp;gt; Receipt)&lt;&#x2F;code&gt; where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Index&lt;&#x2F;code&gt; is the index in the block of the transaction this receipt is for&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Receipt&lt;&#x2F;code&gt; is either &lt;code&gt;TransactionType || ReceiptPayload&lt;&#x2F;code&gt; or &lt;code&gt;LegacyReceipt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransactionType&lt;&#x2F;code&gt; is a positive unsigned 8-bit number between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;0x7f&lt;&#x2F;code&gt; that represents the type of the transaction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; is an opaque byte array whose interpretation is dependent on the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; and defined in future EIPs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LegacyReceipt&lt;&#x2F;code&gt; is &lt;code&gt;rlp([status, cumulativeGasUsed, logsBloom, logs])&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;TransactionType&lt;&#x2F;code&gt; of the receipt &lt;strong&gt;MUST&lt;&#x2F;strong&gt; match the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; of the transaction with a matching &lt;code&gt;Index&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;transactiontype-only-goes-up-to-0x7f&quot;&gt;TransactionType only goes up to 0x7f&lt;&#x2F;h3&gt;
&lt;p&gt;For the forseable future, 0x7f is plenty and it leaves open a number of options for extending the range such as using the high bit as a continuation bit.
This also prevents us from colliding with legacy transaction types, which always start with a byte &lt;code&gt;&amp;gt;= 0xc0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;should-instead-of-must-for-the-transactiontype-being-first-byte-of-signed-data&quot;&gt;&lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; instead of &lt;strong&gt;MUST&lt;&#x2F;strong&gt; for the TransactionType being first byte of signed data&lt;&#x2F;h3&gt;
&lt;p&gt;While it is strongly recommended that all future transactions sign the first byte to ensure that there is no problem with signature reuse, the authors acknowledge that this may not always make sense or be possible.
One example where this isn&#x27;t possible is wrapped legacy transactions that are signature compatible with the legacy signing scheme.
Another potential situation is one where transactions don&#x27;t have a signature in the traditional sense and instead have some other mechanism for determining validity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transactiontype-selection-algorithm&quot;&gt;TransactionType selection algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;There was discussion about defining the &lt;code&gt;TransactionType&lt;&#x2F;code&gt; identifier assignment&#x2F;selection algorithm in this standard.
While it would be nice to have a standardized mechanism for assignment, at the time of writing of this standard there is not a strong need for it so it was deemed out of scope.
A future EIP may introduce a standard for TransactionType identifier assignment if it is deemed necessary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;opaque-byte-array-rather-than-an-rlp-array&quot;&gt;Opaque byte array rather than an RLP array&lt;&#x2F;h3&gt;
&lt;p&gt;By having the second byte on be opaque bytes, rather than an RLP (or other encoding) list, we can support different encoding formats for the transaction payload in the future such as SSZ, LEB128, or a fixed width format.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;origin-and-caller&quot;&gt;ORIGIN and CALLER&lt;&#x2F;h3&gt;
&lt;p&gt;There was discussion about having ORIGIN and CALLER opcodes become dependent on the transaction type, so that each transaction type could define what those opcodes returned.
However, there is a desire to make transaction type opaque to the contracts to discourage contracts treating different types of transactions differently.
There also were concerns over backward compatibility with existing contracts which make assumptions about ORIGIN and CALLER opcodes.
Going forward, we will assume that all transaction types will have an address that reasonably represents a &lt;code&gt;CALLER&lt;&#x2F;code&gt; of the first EVM frame and &lt;code&gt;ORIGIN&lt;&#x2F;code&gt; will be the same address in all cases.
If a transaction type needs to supply additional information to contracts, they will need a new opcode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Clients can differentiate between the legacy transactions and typed transactions by looking at the first byte.
If it starts with a value in the range &lt;code&gt;[0, 0x7f]&lt;&#x2F;code&gt; then it is a new transaction type, if it starts with a value in the range &lt;code&gt;[0xc0, 0xfe]&lt;&#x2F;code&gt; then it is a legacy transaction type.
&lt;code&gt;0xff&lt;&#x2F;code&gt; is not realistic for an RLP encoded transaction, so it is reserved for future use as an extension sentinel value.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;When designing a new 2718 transaction type, it is &lt;strong&gt;STRONGLY&lt;&#x2F;strong&gt; recommended to include the transaction type as the first byte of the signed payload.  If you fail to do this, it is possible that your transaction may be signature compatible with transactions of another type which can introduce security vulnerabilities for users.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>JavaScript Provider Event Emitter</title>
        <published>2020-06-05T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/MicahZoltu</uri>
	</author>
	
	<author>
		<name>Erik Marks</name><uri>https://github.com/rekmarks</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2700/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2701" />
        

        <id>https://wg-eips.ritovision.com/2700/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2700"
            label="EIP-2700" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2700/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard mechanism for JavaScript Ethereum Providers to notify clients about chain state changes when both are able to interface with each other via a shared JavaScript object.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard provides the description of an object that is made available to JavaScript applications which they can use to receive notifications from an Ethereum Provider.  This standard only describes the notification mechanism, it does not specify the payloads that are valid nor does it specify how the client or the provider will discover or agree on payload content.&lt;&#x2F;p&gt;
&lt;p&gt;How&#x2F;where this Ethereum Provider object is exposed is left to future standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;When working within a JavaScript runtime (such as NodeJS, Electron, Browser, etc.) it may be possible for the runtime or a runtime plugin to inject objects into the runtime.  Someone authoring a runtime or a runtime plugin may choose to expose an Ethereum Provider to any JavaScript apps or scripts running within that runtime in order to provide notifications of blockchain state changes.  In order to achieve maximum compatibility between the provider and the client, a standard is necessary for what the shape of that object is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;rfc-2119&quot;&gt;RFC-2119&lt;&#x2F;h3&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;RFC-2119&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EthereumProvider&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;eventName&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	removeListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;eventName&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&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 specific events that can be listened to and the shape of their listener callback functions is left to be defined in separate standards.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;on&lt;&#x2F;code&gt; is called with an &lt;code&gt;eventName&lt;&#x2F;code&gt; that the provider is familiar with then the provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; call the provided &lt;code&gt;listener&lt;&#x2F;code&gt; when the named event occurs.  If the same &lt;code&gt;listener&lt;&#x2F;code&gt; is added multiple times to the same event via &lt;code&gt;on&lt;&#x2F;code&gt;, the provider &lt;strong&gt;MAY&lt;&#x2F;strong&gt; choose to either callback the listener one time or one time per call to &lt;code&gt;on&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;removeListener&lt;&#x2F;code&gt; is called with an &lt;code&gt;eventName&lt;&#x2F;code&gt; and &lt;code&gt;listener&lt;&#x2F;code&gt; that was previously added via &lt;code&gt;on&lt;&#x2F;code&gt; then the provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; decrease the number of times it calls the &lt;code&gt;listener&lt;&#x2F;code&gt; per event by one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is mostly a retrospective EIP meaning it codifies an already existing specification so there isn&#x27;t a lot of room for improving things such as by using a discriminated union object for listener parameters or having a tighter definition of &lt;code&gt;on&lt;&#x2F;code&gt;.  The specific events are intentionally left out of this specification as that set will be an ever-evolving collection and having the first few listed here doesn&#x27;t add value to this specification (especially if, over time, the first few end up deprecated or unused).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The relationship between Ethereum Provider and client is a trusted one, where it is assumed that the user implicitly trusts the Ethereum Provider which is how it managed to get injected into the client, or the client expressly pulled in a connection to it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>JavaScript `request` method RPC transport</title>
        <published>2020-06-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/MicahZoltu</uri>
	</author>
	
	<author>
		<name>Erik Marks</name><uri>https://github.com/rekmarks</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2696/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2697" />
        

        <id>https://wg-eips.ritovision.com/2696/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2696"
            label="EIP-2696" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2696/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard for remote procedure calls between an Ethereum Provider and an Ethereum Client when both are able to interface with each other via a shared JavaScript object.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard provides the description of an object that is made available to JavaScript applications which they can use to communicate with the Ethereum blockchain through.  This standard only describes the transport mechanism, it does not specify the payloads that are valid nor does it specify how the client or the provider will discover or agree on payload content.&lt;&#x2F;p&gt;
&lt;p&gt;How&#x2F;where this Ethereum object is exposed is left to future standards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;When working within a JavaScript runtime (such as NodeJS, Electron, Browser, etc.) it may be possible for the runtime or a runtime plugin to inject objects into the runtime.  Someone authoring a runtime or a runtime plugin may choose to expose an Ethereum Provider to any JavaScript apps or scripts running within that runtime in order to provide indirect access to an Ethereum-like blockchain and potentially signing tools.  In order to achieve maximum compatibility between the provider and the client, a standard is necessary for what the shape of that object is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;rfc-2119&quot;&gt;RFC-2119&lt;&#x2F;h3&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;RFC-2119&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h3&gt;
&lt;p&gt;TypeScript interface definition:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RequestArguments&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;	readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;	readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; object&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EthereumProvider&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RequestArguments&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Promise&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;unknown&lt;&#x2F;span&gt;&lt;span&gt;&amp;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 Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement a &lt;code&gt;request&lt;&#x2F;code&gt; method on the exposed &lt;code&gt;EthereumProvider&lt;&#x2F;code&gt; object.  The &lt;code&gt;request&lt;&#x2F;code&gt; method &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be callable with a single parameter which contains the arguments for the request as defined in the TypeScript &lt;code&gt;interface&lt;&#x2F;code&gt; above.&lt;&#x2F;p&gt;
&lt;p&gt;If the Provider supports a JSON-RPC (https:&#x2F;&#x2F;www.jsonrpc.org&#x2F;specification) request as specified elsewhere, then it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; accept a &lt;code&gt;request&lt;&#x2F;code&gt; call for that JSON-RPC method with the &lt;code&gt;RequestArguments.method&lt;&#x2F;code&gt; argument matching the JSON-RPC &lt;code&gt;method&lt;&#x2F;code&gt; string for the RPC call and the &lt;code&gt;RequestArguments.params&lt;&#x2F;code&gt; matching the &lt;code&gt;params&lt;&#x2F;code&gt; object of the RPC call.  The &lt;code&gt;RequestArguments.params&lt;&#x2F;code&gt; should be encoded as a JavaScript object matching the specified JSON-RPC type, not encoded as a JSON string as would normally be the case when transporting JSON-RPC.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example&lt;&#x2F;h4&gt;
&lt;p&gt;If the JSON-RPC request would contain a payload like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{ &amp;quot;jsonrpc&amp;quot;: &amp;quot;2.0&amp;quot;, &amp;quot;id&amp;quot;: 1, &amp;quot;method&amp;quot;: &amp;quot;do_work&amp;quot;, &amp;quot;params&amp;quot;: [ 5, &amp;quot;hello&amp;quot; ] }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then the matching &lt;code&gt;EthereumProvider.request&lt;&#x2F;code&gt; call would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;declare&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EthereumProvider&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;method&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hello&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt; }&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;results&quot;&gt;Results&lt;&#x2F;h3&gt;
&lt;p&gt;If the Provider supports a JSON-RPC request as specified elsewhere, then it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return an object that matches the expected &lt;code&gt;result&lt;&#x2F;code&gt; definition for the associated JSON-RPC request.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-1&quot;&gt;Example&lt;&#x2F;h4&gt;
&lt;p&gt;If the JSON-RPC response would contain a payload like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{ &amp;quot;jsonrpc&amp;quot;: &amp;quot;2.0&amp;quot;, &amp;quot;id&amp;quot;: 1, &amp;quot;result&amp;quot;: { &amp;quot;color&amp;quot;: &amp;quot;red&amp;quot;, &amp;quot;value&amp;quot;: 5 } }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then the matching &lt;code&gt;EthereumProvider.request&lt;&#x2F;code&gt; response would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; color&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;red&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;h3 id=&quot;errors&quot;&gt;Errors&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderRpcError&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	code&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;code&lt;&#x2F;th&gt;&lt;th&gt;message&lt;&#x2F;th&gt;&lt;th&gt;meaning&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;4001&lt;&#x2F;td&gt;&lt;td&gt;User Rejected Request&lt;&#x2F;td&gt;&lt;td&gt;The user rejected the request.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4100&lt;&#x2F;td&gt;&lt;td&gt;Unauthorized&lt;&#x2F;td&gt;&lt;td&gt;The requested method and&#x2F;or account has not been authorized by the user.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4200&lt;&#x2F;td&gt;&lt;td&gt;Unsupported Method&lt;&#x2F;td&gt;&lt;td&gt;The Provider does not support the requested method.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4900&lt;&#x2F;td&gt;&lt;td&gt;Disconnected&lt;&#x2F;td&gt;&lt;td&gt;The Provider is disconnected from all chains.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4901&lt;&#x2F;td&gt;&lt;td&gt;Chain Disconnected&lt;&#x2F;td&gt;&lt;td&gt;The Provider is not connected to the requested chain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;If the Provider is unable to fulfill a request for any reason, it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; resolve the promise as an error.  The resolved error &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be shaped as a &lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt; defined above whenever possible.  &lt;em&gt;While it is impossible to guaranteed that a JavaScript application will never throw an out of memory or stack overflow error, care should be taken to ensure that promise rejections conform to the above shape whenever possible.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If a &lt;code&gt;code&lt;&#x2F;code&gt; is provided that is listed in the list above, or in the JSON-RPC specification (https:&#x2F;&#x2F;www.jsonrpc.org&#x2F;specification#error_object), or in the associated JSON-RPC request standard being followed, then the error reason &lt;strong&gt;MUST&lt;&#x2F;strong&gt; align with the established meaning of that code and the &lt;code&gt;message&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; match the provided &lt;code&gt;message&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;data&lt;&#x2F;code&gt; field &lt;strong&gt;MAY&lt;&#x2F;strong&gt; contain any data that is relevant to the error or would help the user understand or troubleshoot the error.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;While this standard is perhaps not the greatest mechanism for communicating between an application and a blockchain, it is closely aligned with established practices within the community so migration from existing systems to this one should be relatively easy.  Most communication is currently done via JSON-RPC, so aligning with the JSON-RPC standard was desired to enable quick integration with existing systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The relationship between Ethereum Provider and client is a trusted one, where it is assumed that the user implicitly trusts the Ethereum Provider which is how it managed to get injected into the client, or the client expressly pulled in a connection to it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Revised Ethereum Smart Contract Packaging Standard (EthPM v3)</title>
        <published>2020-05-26T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>g. nicholas d’andrea</name><uri>https://github.com/gnidan</uri>
	</author>
	
	<author>
		<name>Piper Merriam</name><uri>https://github.com/pipermerriam</uri>
	</author>
	
	<author>
		<name>Nick Gheorghita</name><uri>https://github.com/njgheorghita</uri>
	</author>
	
	<author>
		<name>Christian Reitwiessner</name><uri>https://github.com/chriseth</uri>
	</author>
	
	<author>
		<name>Ben Hauser</name><uri>https://github.com/iamdefinitelyahuman</uri>
	</author>
	
	<author>
		<name>Bryant Eisenbach</name><uri>https://github.com/fubuloubu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2678/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/ethpm-v3-specification-working-group/4086" />
        

        <id>https://wg-eips.ritovision.com/2678/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2678"
            label="ERC-2678" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2678/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A data format describing a smart contract software package.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a data format for &lt;em&gt;package manifest&lt;&#x2F;em&gt; documents,
representing a package of one or more smart contracts, optionally
including source code and any&#x2F;all deployed instances across multiple
networks. Package manifests are minified JSON objects, to be distributed
via content addressable storage networks, such as IPFS. Packages
are then published to on-chain EthPM registries, defined in
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1319&#x2F;&quot;&gt;EIP-1319&lt;&#x2F;a&gt;, from where they can be freely accessed.&lt;&#x2F;p&gt;
&lt;p&gt;This document presents a natural language description of a formal
specification for version &lt;strong&gt;3&lt;&#x2F;strong&gt; of this format.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This standard aims to encourage the Ethereum development ecosystem
towards software best practices around code reuse. By defining an open,
community-driven package data format standard, this effort seeks to
provide support for package management tools development by offering a
general-purpose solution that has been designed with observed common
practices in mind.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Updates the schema for a &lt;em&gt;package manifest&lt;&#x2F;em&gt; to be compatible with
the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;latest&#x2F;metadata.html&quot;&gt;metadata&lt;&#x2F;a&gt; output for compilers.&lt;&#x2F;li&gt;
&lt;li&gt;Updates the &lt;code&gt;&quot;sources&quot;&lt;&#x2F;code&gt; object definition to support a wider range of source file types and serve as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;latest&#x2F;using-the-compiler.html#compiler-input-and-output-json-description&quot;&gt;JSON input&lt;&#x2F;a&gt; for a compiler.&lt;&#x2F;li&gt;
&lt;li&gt;Moves compiler definitions to a top-level &lt;code&gt;&quot;compilers&quot;&lt;&#x2F;code&gt; array in order to:
&lt;ul&gt;
&lt;li&gt;Simplify the links between a compiler version, sources, and the
compiled assets.&lt;&#x2F;li&gt;
&lt;li&gt;Simplify packages that use multiple compiler versions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Updates key formatting from &lt;code&gt;snake_case&lt;&#x2F;code&gt; to &lt;code&gt;camelCase&lt;&#x2F;code&gt; to be
more consistent with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;google.github.io&#x2F;styleguide&#x2F;jsoncstyleguide.xml?showone=Property_Name_Format#Property_Name_Format&quot;&gt;JSON convention&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;guiding-principles&quot;&gt;Guiding Principles&lt;&#x2F;h3&gt;
&lt;p&gt;This specification makes the following assumptions about the document
lifecycle.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Package manifests are intended to be generated programmatically by
package management software as part of the release process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package manifests will be consumed by package managers during tasks
like installing package dependencies or building and deploying new
releases.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package manifests will typically &lt;strong&gt;not&lt;&#x2F;strong&gt; be stored alongside the
source, but rather by package registries &lt;em&gt;or&lt;&#x2F;em&gt; referenced by package
registries and stored in something akin to IPFS.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package manifests can be used to verify public deployments of source
contracts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;use-cases&quot;&gt;Use Cases&lt;&#x2F;h3&gt;
&lt;p&gt;The following use cases were considered during the creation of this
specification.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;owned&lt;&#x2F;strong&gt;: A package which contains contracts which are not meant to be used by themselves but rather as base contracts to provide functionality to other contracts through inheritance.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;transferable&lt;&#x2F;strong&gt;: A package which has a single dependency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;standard-token&lt;&#x2F;strong&gt;: A package which contains a reusable contract.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;safe-math-lib&lt;&#x2F;strong&gt;: A package which contains deployed instance of one of the package contracts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;piper-coin&lt;&#x2F;strong&gt;: A package which contains a deployed instance of a reusable contract from a dependency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;escrow&lt;&#x2F;strong&gt;: A package which contains a deployed instance of a local contract which is linked against a deployed instance of a local library.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;wallet&lt;&#x2F;strong&gt;: A package with a deployed instance of a local contract which is linked against a deployed instance of a library from a dependency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;wallet-with-send&lt;&#x2F;strong&gt;: A package with a deployed instance which links against a deep dependency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;simple-auction&lt;&#x2F;strong&gt;: Compiler &lt;code&gt;&quot;metadata&quot;&lt;&#x2F;code&gt; field output.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;package-specification&quot;&gt;Package Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;conventions&quot;&gt;Conventions&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;rfc2119&quot;&gt;RFC2119&lt;&#x2F;h4&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;prefixed-vs-unprefixed&quot;&gt;Prefixed vs Unprefixed&lt;&#x2F;h4&gt;
&lt;p&gt;A &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#prefixed&quot;&gt;prefixed&lt;&#x2F;a&gt; hexadecimal value begins with &lt;code&gt;0x&lt;&#x2F;code&gt;.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#unprefixed&quot;&gt;Unprefixed&lt;&#x2F;a&gt; values have no prefix. Unless otherwise
specified, all hexadecimal values &lt;strong&gt;should&lt;&#x2F;strong&gt; be represented with the
&lt;code&gt;0x&lt;&#x2F;code&gt; prefix.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prefixed&lt;&#x2F;strong&gt;: &lt;code&gt;0xdeadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Unprefixed&lt;&#x2F;strong&gt;: &lt;code&gt;deadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;document-format&quot;&gt;Document Format&lt;&#x2F;h3&gt;
&lt;p&gt;The canonical format is a single JSON object. Packages &lt;strong&gt;must&lt;&#x2F;strong&gt; conform
to the following serialization rules.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The document &lt;strong&gt;must&lt;&#x2F;strong&gt; be tightly packed, meaning no linebreaks or
extra whitespace.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The keys in all objects &lt;strong&gt;must&lt;&#x2F;strong&gt; be sorted alphabetically.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Duplicate keys in the same object are invalid.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The document &lt;strong&gt;must&lt;&#x2F;strong&gt; use
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;UTF-8&quot;&gt;UTF-8&lt;&#x2F;a&gt;
encoding.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The document &lt;strong&gt;must&lt;&#x2F;strong&gt; not have a trailing newline.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To ensure backwards compatibility, &lt;code&gt;manifest_version&lt;&#x2F;code&gt; is a forbidden
top-level key.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;document-specification&quot;&gt;Document Specification&lt;&#x2F;h3&gt;
&lt;p&gt;The following fields are defined for the package. Custom fields &lt;strong&gt;may&lt;&#x2F;strong&gt;
be included. Custom fields &lt;strong&gt;should&lt;&#x2F;strong&gt; be prefixed with &lt;code&gt;x-&lt;&#x2F;code&gt; to prevent
name collisions with future versions of the specification.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;See Also&lt;&#x2F;strong&gt;: Formalized (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;json-schema.org&quot;&gt;JSON-Schema&lt;&#x2F;a&gt;) version of this specification: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;.&#x2F;assets&#x2F;package.spec.json&quot;&gt;package.spec.json&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Jump To&lt;&#x2F;strong&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#object-definitions&quot;&gt;Definitions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ethpm-manifest-version&quot;&gt;EthPM Manifest Version&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;manifest&lt;&#x2F;code&gt; field defines the specification version that this
document conforms to.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;must&lt;&#x2F;strong&gt; include this field.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;manifest&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Allowed Values&lt;&#x2F;strong&gt;: &lt;code&gt;ethpm&#x2F;3&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;package-name&quot;&gt;Package Name&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;name&lt;&#x2F;code&gt; field defines a human readable name for this package.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;should&lt;&#x2F;strong&gt; include this field to be released on an EthPM
registry.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package names &lt;strong&gt;must&lt;&#x2F;strong&gt; begin with a lowercase letter and be
comprised of only the lowercase letters &lt;code&gt;a-z&lt;&#x2F;code&gt;, numeric characters &lt;code&gt;0-9&lt;&#x2F;code&gt;, and the
dash character &lt;code&gt;-&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Package names &lt;strong&gt;must&lt;&#x2F;strong&gt; not exceed 255 characters in length.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: If &lt;code&gt;version&lt;&#x2F;code&gt; is included.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;must&lt;&#x2F;strong&gt; match the regular expression &lt;code&gt;^[a-z][-a-z0-9]{0,255}$&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;package-version&quot;&gt;Package Version&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;version&lt;&#x2F;code&gt; field declares the version number of this release.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;should&lt;&#x2F;strong&gt; include this field to be released on an EthPM
registry.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This value &lt;strong&gt;should&lt;&#x2F;strong&gt; conform to the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;semver&lt;&#x2F;a&gt; version numbering
specification.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: If &lt;code&gt;name&lt;&#x2F;code&gt; is included.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;version&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;package-metadata&quot;&gt;Package Metadata&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;meta&lt;&#x2F;code&gt; field defines a location for metadata about the package which
is not integral in nature for package installation, but may be important
or convenient to have on-hand for other reasons.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This field &lt;strong&gt;should&lt;&#x2F;strong&gt; be included in all Packages.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;meta&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-package-meta-object&quot;&gt;Package Meta Object&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;sources&lt;&#x2F;code&gt; field defines a source tree that &lt;strong&gt;should&lt;&#x2F;strong&gt; comprise the
full source tree necessary to recompile the contracts contained in this
release.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;sources&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Object (String: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-source-object&quot;&gt;Sources Object&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;contract-types&quot;&gt;Contract Types&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;contractTypes&lt;&#x2F;code&gt; field hosts the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Types&lt;&#x2F;a&gt; which have been included in this release.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;should&lt;&#x2F;strong&gt; only include contract types that can be found in
the source files for this package.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;should not&lt;&#x2F;strong&gt; include contract types from dependencies.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Packages &lt;strong&gt;should not&lt;&#x2F;strong&gt; include abstract contracts in the contract
types section of a release.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;contractTypes&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Object (String: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-contract-type-object&quot;&gt;Contract Type Object&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: Keys &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract Aliases&lt;&#x2F;a&gt;. &lt;br&gt; Values &lt;strong&gt;must&lt;&#x2F;strong&gt; conform to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-contract-type-object&quot;&gt;Contract Type Object&lt;&#x2F;a&gt; definition.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;compilers&quot;&gt;Compilers&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;compilers&lt;&#x2F;code&gt; field holds the information about the compilers and
their settings that have been used to generate the various
&lt;code&gt;contractTypes&lt;&#x2F;code&gt; included in this release.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;compilers&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Array (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-compiler-information-object&quot;&gt;Compiler Information Object&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;deployments&quot;&gt;Deployments&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;deployments&lt;&#x2F;code&gt; field holds the information for the chains on which
this release has &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instances&lt;&#x2F;a&gt; as well
as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract Types&lt;&#x2F;a&gt; and other deployment
details for those deployed contract instances. The set of chains defined
by the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#bip122-uri&quot;&gt;BIP122 URI&lt;&#x2F;a&gt; keys for this object &lt;strong&gt;must&lt;&#x2F;strong&gt; be
unique. There cannot be two different URI keys in a deployments field
representing the same blockchain.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;deployments&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Object (String: Object(String: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-contract-instance-object&quot;&gt;Contract Instance Object&lt;&#x2F;a&gt;))&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: Keys &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid BIP122 URI chain definition. &lt;br&gt;Values &lt;strong&gt;must&lt;&#x2F;strong&gt; be objects which conform to the following format:&lt;br&gt;- Keys &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance-name&quot;&gt;Contract Instance Names&lt;&#x2F;a&gt;&lt;br&gt;- Values &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-contract-instance-object&quot;&gt;Contract Instance Object&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;build-dependencies&quot;&gt;Build Dependencies&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;buildDependencies&lt;&#x2F;code&gt; field defines a key&#x2F;value mapping of EthPM
packages that this project depends on.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;buildDependencies&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Object (String: String)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: Keys &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package-name&quot;&gt;package names&lt;&#x2F;a&gt;.&lt;br&gt;Values &lt;strong&gt;must&lt;&#x2F;strong&gt; be a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#content-addressable-uri&quot;&gt;Content Addressable URI&lt;&#x2F;a&gt; which resolves to a valid package that conforms the same EthPM manifest version as its parent.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;object-definitions&quot;&gt;Object Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;Definitions for different objects used within the Package. All objects
allow custom fields to be included. Custom fields &lt;strong&gt;should&lt;&#x2F;strong&gt; be prefixed
with &lt;code&gt;x-&lt;&#x2F;code&gt; to prevent name collisions with future versions of the
specification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-link-reference-object&quot;&gt;The &lt;em&gt;Link Reference&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link Reference&lt;&#x2F;a&gt; object has the following
key&#x2F;value pairs. All link references are assumed to be associated with
some corresponding &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#bytecode&quot;&gt;Bytecode&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;offsets-offsets&quot;&gt;Offsets: &lt;code&gt;offsets&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;offsets&lt;&#x2F;code&gt; field is an array of integers, corresponding to each of
the start positions where the link reference appears in the bytecode.
Locations are 0-indexed from the beginning of the bytes representation
of the corresponding bytecode. This field is invalid if it references a
position that is beyond the end of the bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Array&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;length-length&quot;&gt;Length: &lt;code&gt;length&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;length&lt;&#x2F;code&gt; field is an integer which defines the length in bytes of
the link reference. This field is invalid if the end of the defined link
reference exceeds the end of the bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Integer&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;name-name&quot;&gt;Name: &lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;name&lt;&#x2F;code&gt; field is a string which &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#identifier&quot;&gt;Identifier&lt;&#x2F;a&gt;. Any link references which &lt;strong&gt;should&lt;&#x2F;strong&gt; be
linked with the same link value &lt;strong&gt;should&lt;&#x2F;strong&gt; be given the same name.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;must&lt;&#x2F;strong&gt; conform to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#identifier&quot;&gt;Identifier&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-link-value-object&quot;&gt;The &lt;em&gt;Link Value&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;Describes a single &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-value&quot;&gt;Link Value&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;Link Value object&lt;&#x2F;strong&gt; is defined to have the following key&#x2F;value
pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;offsets-offsets-1&quot;&gt;Offsets: &lt;code&gt;offsets&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;offsets&lt;&#x2F;code&gt; field defines the locations within the corresponding
bytecode where the &lt;code&gt;value&lt;&#x2F;code&gt; for this link value was written. These
locations are 0-indexed from the beginning of the bytes representation
of the corresponding bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: Integer&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: See below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Format&lt;&#x2F;p&gt;
&lt;p&gt;Array of integers, where each integer &lt;strong&gt;must&lt;&#x2F;strong&gt; conform to all of the
following.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;greater than or equal to zero&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;strictly less than the length of the unprefixed hexadecimal
representation of the corresponding bytecode.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;type-type&quot;&gt;Type: &lt;code&gt;type&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;type&lt;&#x2F;code&gt; field defines the &lt;code&gt;value&lt;&#x2F;code&gt; type for determining what is
encoded when &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#linking&quot;&gt;linking&lt;&#x2F;a&gt; the corresponding bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Allowed Values&lt;&#x2F;strong&gt;: &lt;code&gt;&quot;literal&quot;&lt;&#x2F;code&gt; for bytecode literals.&lt;br&gt;&lt;code&gt;&quot;reference&quot;&lt;&#x2F;code&gt; for named references to a particular &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instance&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;value-value&quot;&gt;Value: &lt;code&gt;value&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;value&lt;&#x2F;code&gt; field defines the value which should be written when &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#linking&quot;&gt;linking&lt;&#x2F;a&gt; the corresponding bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: Determined based on &lt;code&gt;type&lt;&#x2F;code&gt;, see below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Format&lt;&#x2F;p&gt;
&lt;p&gt;For static value &lt;em&gt;literals&lt;&#x2F;em&gt; (e.g. address), value &lt;strong&gt;must&lt;&#x2F;strong&gt; be a 0x-prefixed
hexadecimal string representing bytes.&lt;&#x2F;p&gt;
&lt;p&gt;To reference the address of a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract
Instance&lt;&#x2F;a&gt; from the current package the value
should be the name of that contract instance.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This value &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance-name&quot;&gt;Contract Instance
Name&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The chain definition under which the contract instance that this
link value belongs to must contain this value within its keys.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This value &lt;strong&gt;may not&lt;&#x2F;strong&gt; reference the same contract instance that
this link value belongs to.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To reference a contract instance from a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package&quot;&gt;Package&lt;&#x2F;a&gt; from
somewhere within the dependency tree the value is constructed as
follows.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Let &lt;code&gt;[p1, p2, .. pn]&lt;&#x2F;code&gt; define a path down the dependency tree.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Each of &lt;code&gt;p1, p2, pn&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid package names.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;p1&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; be present in keys of the &lt;code&gt;buildDependencies&lt;&#x2F;code&gt; for the
current package.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For every &lt;code&gt;pn&lt;&#x2F;code&gt; where &lt;code&gt;n &amp;gt; 1&lt;&#x2F;code&gt;, &lt;code&gt;pn&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; be present in the keys
of the &lt;code&gt;buildDependencies&lt;&#x2F;code&gt; of the package for &lt;code&gt;pn-1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The value is represented by the string
&lt;code&gt;&amp;lt;p1&amp;gt;:&amp;lt;p2&amp;gt;:&amp;lt;...&amp;gt;:&amp;lt;pn&amp;gt;:&amp;lt;contract-instance&amp;gt;&lt;&#x2F;code&gt; where all of &lt;code&gt;&amp;lt;p1&amp;gt;&lt;&#x2F;code&gt;,
&lt;code&gt;&amp;lt;p2&amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;&amp;lt;pn&amp;gt;&lt;&#x2F;code&gt; are valid package names and &lt;code&gt;&amp;lt;contract-instance&amp;gt;&lt;&#x2F;code&gt; is
a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-name&quot;&gt;Contract Name&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;contract-instance&amp;gt;&lt;&#x2F;code&gt; value &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance-name&quot;&gt;Contract
Instance Name&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Within the package of the dependency defined by &lt;code&gt;&amp;lt;pn&amp;gt;&lt;&#x2F;code&gt;, all of the
following must be satisfiable:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There &lt;strong&gt;must&lt;&#x2F;strong&gt; be &lt;em&gt;exactly&lt;&#x2F;em&gt; one chain defined under the
&lt;code&gt;deployments&lt;&#x2F;code&gt; key which matches the chain definition that this
link value is nested under.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;contract-instance&amp;gt;&lt;&#x2F;code&gt; value &lt;strong&gt;must&lt;&#x2F;strong&gt; be present in the keys
of the matching chain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-bytecode-object&quot;&gt;The &lt;em&gt;Bytecode&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A bytecode object has the following key&#x2F;value pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bytecode-bytecode&quot;&gt;Bytecode: &lt;code&gt;bytecode&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;bytecode&lt;&#x2F;code&gt; field is a string containing the &lt;code&gt;0x&lt;&#x2F;code&gt; prefixed
hexadecimal representation of the bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;code&gt;0x&lt;&#x2F;code&gt; prefixed hexadecimal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;link-references-linkreferences&quot;&gt;Link References: &lt;code&gt;linkReferences&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;linkReferences&lt;&#x2F;code&gt; field defines the locations in the corresponding
bytecode which require &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#linking&quot;&gt;linking&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: All values &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-link-reference-object&quot;&gt;Link Reference objects&lt;&#x2F;a&gt;. See also below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Format&lt;&#x2F;p&gt;
&lt;p&gt;This field is considered invalid if &lt;em&gt;any&lt;&#x2F;em&gt; of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link
References&lt;&#x2F;a&gt; are invalid when applied to the
corresponding &lt;code&gt;bytecode&lt;&#x2F;code&gt; field, &lt;em&gt;or&lt;&#x2F;em&gt; if any of the link references
intersect.&lt;&#x2F;p&gt;
&lt;p&gt;Intersection is defined as two link references which overlap.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;link-dependencies-linkdependencies&quot;&gt;Link Dependencies: &lt;code&gt;linkDependencies&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;linkDependencies&lt;&#x2F;code&gt; defines the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-value&quot;&gt;Link Values&lt;&#x2F;a&gt; that
have been used to link the corresponding bytecode.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: All values &lt;strong&gt;must&lt;&#x2F;strong&gt; be valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-link-value-object&quot;&gt;Link Value objects&lt;&#x2F;a&gt;. See also below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Format&lt;&#x2F;p&gt;
&lt;p&gt;Validation of this field includes the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two link value objects &lt;strong&gt;must not&lt;&#x2F;strong&gt; contain any of the same values
for &lt;code&gt;offsets&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Each &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-link-value-object&quot;&gt;link value object&lt;&#x2F;a&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; have a
corresponding &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-link-reference-object&quot;&gt;link reference object&lt;&#x2F;a&gt; under
the &lt;code&gt;linkReferences&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The length of the resolved &lt;code&gt;value&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; be equal to the &lt;code&gt;length&lt;&#x2F;code&gt;
of the corresponding &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link Reference&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-package-meta-object&quot;&gt;The &lt;em&gt;Package Meta&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;em&gt;Package Meta&lt;&#x2F;em&gt; object is defined to have the following key&#x2F;value
pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;authors&quot;&gt;Authors&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;authors&lt;&#x2F;code&gt; field defines a list of human readable names for the
authors of this package. Packages &lt;strong&gt;may&lt;&#x2F;strong&gt; include this field.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;authors&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array(String)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;license&quot;&gt;License&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;license&lt;&#x2F;code&gt; field declares the license associated with this package.
This value &lt;strong&gt;should&lt;&#x2F;strong&gt; conform to the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;spdx.org&#x2F;licenses&#x2F;&quot;&gt;SPDX&lt;&#x2F;a&gt;
format. Packages &lt;strong&gt;should&lt;&#x2F;strong&gt; include this field. If a file &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-source-object&quot;&gt;Source
Object&lt;&#x2F;a&gt; defines its own license, that license takes
precedence for that particular file over this package-scoped &lt;code&gt;meta&lt;&#x2F;code&gt;
license.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;license&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;description&quot;&gt;Description&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;description&lt;&#x2F;code&gt; field provides additional detail that may be relevant
for the package. Packages &lt;strong&gt;may&lt;&#x2F;strong&gt; include this field.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;description&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;keywords&quot;&gt;Keywords&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;keywords&lt;&#x2F;code&gt; field provides relevant keywords related to this package.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;keywords&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array(String)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;links&quot;&gt;Links&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;links&lt;&#x2F;code&gt; field provides URIs to relevant resources associated with
this package. When possible, authors &lt;strong&gt;should&lt;&#x2F;strong&gt; use the following keys
for the following common resources.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;website&lt;&#x2F;code&gt;: Primary website for the package.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;documentation&lt;&#x2F;code&gt;: Package Documentation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;repository&lt;&#x2F;code&gt;: Location of the project source code.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;links&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object (String: String)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-sources-object&quot;&gt;The &lt;em&gt;Sources&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;em&gt;Sources&lt;&#x2F;em&gt; object is defined to have the following fields.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: A unique identifier for the source file. (String)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-source-object&quot;&gt;Source Object&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-source-object&quot;&gt;The &lt;em&gt;Source&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;checksum-checksum&quot;&gt;Checksum: &lt;code&gt;checksum&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Hash of the source file.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Only &lt;strong&gt;if&lt;&#x2F;strong&gt; the &lt;code&gt;content&lt;&#x2F;code&gt; field is missing and none of the provided URLs contain a content hash.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;checksum&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-checksum-object&quot;&gt;Checksum Object&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;urls-urls&quot;&gt;URLS: &lt;code&gt;urls&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Array of urls that resolve to the same source file.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Urls &lt;strong&gt;should&lt;&#x2F;strong&gt; be stored on a content-addressable filesystem.
&lt;strong&gt;If&lt;&#x2F;strong&gt; they are not, then either &lt;code&gt;content&lt;&#x2F;code&gt; or &lt;code&gt;checksum&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; be
included.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Urls &lt;strong&gt;must&lt;&#x2F;strong&gt; be prefixed with a scheme.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the resulting document is a directory the key &lt;strong&gt;should&lt;&#x2F;strong&gt; be
interpreted as a directory path.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the resulting document is a file the key &lt;strong&gt;should&lt;&#x2F;strong&gt; be
interpreted as a file path.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: If &lt;code&gt;content&lt;&#x2F;code&gt; is not included.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;urls&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: Array(String)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;content-content&quot;&gt;Content: &lt;code&gt;content&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Inlined contract source. If both &lt;code&gt;urls&lt;&#x2F;code&gt; and &lt;code&gt;content&lt;&#x2F;code&gt; are provided, the &lt;code&gt;content&lt;&#x2F;code&gt; value
&lt;strong&gt;must&lt;&#x2F;strong&gt; match the content of the files identified in &lt;code&gt;urls&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: If &lt;code&gt;urls&lt;&#x2F;code&gt; is not included.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;content&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;install-path-installpath&quot;&gt;Install Path: &lt;code&gt;installPath&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Filesystem path of source file.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be a relative filesystem path that begins with a &lt;code&gt;.&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; resolve to a path that is within the current virtual
working directory.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be unique across all included sources.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Must not&lt;&#x2F;strong&gt; contain &lt;code&gt;..&#x2F;&lt;&#x2F;code&gt; to avoid accessing files outside of
the source folder in improper implementations.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: This field &lt;strong&gt;must&lt;&#x2F;strong&gt; be included for the package to be writable to disk.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;installPath&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: String&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;type-type-1&quot;&gt;Type: &lt;code&gt;type&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;type&lt;&#x2F;code&gt; field declares the type of the source file. The field
&lt;strong&gt;should&lt;&#x2F;strong&gt; be one of the following values: &lt;code&gt;solidity&lt;&#x2F;code&gt;, &lt;code&gt;vyper&lt;&#x2F;code&gt;,
&lt;code&gt;abi-json&lt;&#x2F;code&gt;, &lt;code&gt;solidity-ast-json&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;type&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;license-license&quot;&gt;License: &lt;code&gt;license&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;license&lt;&#x2F;code&gt; field declares the type of license associated with
this source file. When defined, this license overrides the
package-scoped &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#license&quot;&gt;meta license&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;license&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;&#x2F;strong&gt;: String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-checksum-object&quot;&gt;The &lt;em&gt;Checksum&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;em&gt;Checksum&lt;&#x2F;em&gt; object is defined to have the following key&#x2F;value pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;algorithm-algorithm&quot;&gt;Algorithm: &lt;code&gt;algorithm&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;algorithm&lt;&#x2F;code&gt; used to generate the corresponding hash. Possible
algorithms include, but are not limited to &lt;code&gt;sha3&lt;&#x2F;code&gt;, &lt;code&gt;sha256&lt;&#x2F;code&gt;, &lt;code&gt;md5&lt;&#x2F;code&gt;,
&lt;code&gt;keccak256&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;hash-hash&quot;&gt;Hash: &lt;code&gt;hash&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;hash&lt;&#x2F;code&gt; of a source files contents generated with the corresponding
algorithm.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-contract-type-object&quot;&gt;The &lt;em&gt;Contract Type&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;em&gt;Contract Type&lt;&#x2F;em&gt; object is defined to have the following key&#x2F;value
pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-name-contractname&quot;&gt;Contract Name: &lt;code&gt;contractName&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;contractName&lt;&#x2F;code&gt; field defines the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-name&quot;&gt;Contract
Name&lt;&#x2F;a&gt; for this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: If the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-name&quot;&gt;Contract Name&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract Alias&lt;&#x2F;a&gt; are not the same.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-name&quot;&gt;Contract Name&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;source-id-sourceid&quot;&gt;Source ID: &lt;code&gt;sourceId&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The global source identifier for the source file from which this
contract type was generated.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; match a unique source ID included in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-sources-object&quot;&gt;Sources Object&lt;&#x2F;a&gt; for this package.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;deployment-bytecode-deploymentbytecode&quot;&gt;Deployment Bytecode: &lt;code&gt;deploymentBytecode&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;deploymentBytecode&lt;&#x2F;code&gt; field defines the bytecode for this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-bytecode-object&quot;&gt;Bytecode object&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;runtime-bytecode-runtimebytecode&quot;&gt;Runtime Bytecode: &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt; field defines the unlinked &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed runtime
portion of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#bytecode&quot;&gt;Bytecode&lt;&#x2F;a&gt; for this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-bytecode-object&quot;&gt;Bytecode object&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;abi-abi&quot;&gt;ABI: &lt;code&gt;abi&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Ethereum-Contract-ABI#json&quot;&gt;Ethereum Contract ABI JSON&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;userdoc-userdoc&quot;&gt;UserDoc: &lt;code&gt;userdoc&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Ethereum-Natural-Specification-Format#user-documentation&quot;&gt;UserDoc&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;devdoc-devdoc&quot;&gt;DevDoc: &lt;code&gt;devdoc&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Ethereum-Natural-Specification-Format#developer-documentation&quot;&gt;DevDoc&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-contract-instance-object&quot;&gt;The &lt;em&gt;Contract Instance&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;strong&gt;Contract Instance Object&lt;&#x2F;strong&gt; represents a single deployed &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract
Instance&lt;&#x2F;a&gt; and is defined to have the following
key&#x2F;value pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-type-contracttype&quot;&gt;Contract Type: &lt;code&gt;contractType&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;contractType&lt;&#x2F;code&gt; field defines the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt; for this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract
Instance&lt;&#x2F;a&gt;. This can reference any of the
contract types included in this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package&quot;&gt;Package&lt;&#x2F;a&gt; &lt;em&gt;or&lt;&#x2F;em&gt; any of the
contract types found in any of the package dependencies from the
&lt;code&gt;buildDependencies&lt;&#x2F;code&gt; section of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package-manifest&quot;&gt;Package
Manifest&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: See below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Format&lt;&#x2F;p&gt;
&lt;p&gt;Values for this field &lt;strong&gt;must&lt;&#x2F;strong&gt; conform to &lt;em&gt;one of&lt;&#x2F;em&gt; the two formats
herein.&lt;&#x2F;p&gt;
&lt;p&gt;To reference a contract type from this Package, use the format
&lt;code&gt;&amp;lt;contract-alias&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;contract-alias&amp;gt;&lt;&#x2F;code&gt; value &lt;strong&gt;must&lt;&#x2F;strong&gt; be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract
Alias&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The value &lt;strong&gt;must&lt;&#x2F;strong&gt; be present in the keys of the &lt;code&gt;contractTypes&lt;&#x2F;code&gt;
section of this Package.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To reference a contract type from a dependency, use the format
&lt;code&gt;&amp;lt;package-name&amp;gt;:&amp;lt;contract-alias&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;package-name&amp;gt;&lt;&#x2F;code&gt; value &lt;strong&gt;must&lt;&#x2F;strong&gt; be present in the keys of the
&lt;code&gt;buildDependencies&lt;&#x2F;code&gt; of this Package.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;contract-alias&amp;gt;&lt;&#x2F;code&gt; value &lt;strong&gt;must&lt;&#x2F;strong&gt; be be a valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract
Alias&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The resolved package for &lt;code&gt;&amp;lt;package-name&amp;gt;&lt;&#x2F;code&gt; must contain the
&lt;code&gt;&amp;lt;contract-alias&amp;gt;&lt;&#x2F;code&gt; value in the keys of the &lt;code&gt;contractTypes&lt;&#x2F;code&gt; section.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;address-address&quot;&gt;Address: &lt;code&gt;address&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;address&lt;&#x2F;code&gt; field defines the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#address&quot;&gt;Address&lt;&#x2F;a&gt; of the
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instance&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: Hex encoded &lt;code&gt;0x&lt;&#x2F;code&gt; prefixed Ethereum address matching the regular expression &lt;code&gt;^0x[0-9a-fA-F]{40}$&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;transaction-transaction&quot;&gt;Transaction: &lt;code&gt;transaction&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;transaction&lt;&#x2F;code&gt; field defines the transaction hash in which this
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instance&lt;&#x2F;a&gt; was created.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;code&gt;0x&lt;&#x2F;code&gt; prefixed hex encoded transaction hash.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;block-block&quot;&gt;Block: &lt;code&gt;block&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;block&lt;&#x2F;code&gt; field defines the block hash in which this the transaction
which created this &lt;em&gt;contract instance&lt;&#x2F;em&gt; was mined.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;code&gt;0x&lt;&#x2F;code&gt; prefixed hex encoded block hash.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;runtime-bytecode-runtimebytecode-1&quot;&gt;Runtime Bytecode: &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt; field defines the runtime portion of bytecode for
this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instance&lt;&#x2F;a&gt;. When present, the
value from this field supersedes the &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt; from the
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract Type&lt;&#x2F;a&gt; for this &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract
Instance&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; conform to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#the-bytecode-object&quot;&gt;Bytecode Object&lt;&#x2F;a&gt; format.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Every entry in the &lt;code&gt;linkReferences&lt;&#x2F;code&gt; for this bytecode &lt;strong&gt;must&lt;&#x2F;strong&gt; have a
corresponding entry in the &lt;code&gt;linkDependencies&lt;&#x2F;code&gt; section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-compiler-information-object&quot;&gt;The &lt;em&gt;Compiler Information&lt;&#x2F;em&gt; Object&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;compilers&lt;&#x2F;code&gt; field defines the various compilers and settings used
during compilation of any &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract Types&lt;&#x2F;a&gt; or
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract Instance&lt;&#x2F;a&gt; included in this package.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;em&gt;Compiler Information&lt;&#x2F;em&gt; object is defined to have the following
key&#x2F;value pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;name-name-1&quot;&gt;Name: &lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;name&lt;&#x2F;code&gt; field defines which compiler was used in compilation.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;version-version&quot;&gt;Version: &lt;code&gt;version&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;version&lt;&#x2F;code&gt; field defines the version of the compiler. The field
&lt;strong&gt;should&lt;&#x2F;strong&gt; be OS agnostic (OS not included in the string) and take the
form of either the stable version in
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;semver&lt;&#x2F;a&gt; format or if built on a
nightly should be denoted in the form of &lt;code&gt;&amp;lt;semver&amp;gt;-&amp;lt;commit-hash&amp;gt;&lt;&#x2F;code&gt; ex:
&lt;code&gt;0.4.8-commit.60cc1668&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: Yes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;version&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  String&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;settings-settings&quot;&gt;Settings: &lt;code&gt;settings&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;settings&lt;&#x2F;code&gt; field defines any settings or configuration that was used
in compilation. For the &lt;code&gt;&quot;solc&quot;&lt;&#x2F;code&gt; compiler, this &lt;strong&gt;should&lt;&#x2F;strong&gt; conform to
the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;latest&#x2F;using-the-compiler.html#compiler-input-and-output-json-description&quot;&gt;Compiler Input and Output
Description&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;settings&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Object&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;contract-types-contracttypes&quot;&gt;Contract Types: &lt;code&gt;contractTypes&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;A list of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract Alias&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract Types&lt;&#x2F;a&gt; in this package
that used this compiler to generate its outputs.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;All &lt;code&gt;contractTypes&lt;&#x2F;code&gt; that locally declare &lt;code&gt;runtimeBytecode&lt;&#x2F;code&gt;
&lt;strong&gt;should&lt;&#x2F;strong&gt; be attributed for by a compiler object.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A single &lt;code&gt;contractTypes&lt;&#x2F;code&gt; &lt;strong&gt;must&lt;&#x2F;strong&gt; not be attributed to more than one
compiler.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;&#x2F;strong&gt;: No&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt;: &lt;code&gt;contractTypes&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;&#x2F;strong&gt;:  Array(&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract Alias&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bip122-uri&quot;&gt;BIP122 URI&lt;&#x2F;h3&gt;
&lt;p&gt;BIP122 URIs are used to define a blockchain via a subset of the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0122.mediawiki&quot;&gt;BIP-122&lt;&#x2F;a&gt;
spec.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;blockchain:&#x2F;&#x2F;&amp;lt;genesis_hash&amp;gt;&#x2F;block&#x2F;&amp;lt;latest confirmed block hash&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;genesis hash&amp;gt;&lt;&#x2F;code&gt; represents the blockhash of the first block on the
chain, and &lt;code&gt;&amp;lt;latest confirmed block hash&amp;gt;&lt;&#x2F;code&gt; represents the hash of the
latest block that’s been reliably confirmed (package managers should be
free to choose their desired level of confirmations).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;glossary&quot;&gt;Glossary&lt;&#x2F;h3&gt;
&lt;p&gt;The terms in this glossary have been updated to reflect the changes made
in V3.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;abi&quot;&gt;ABI&lt;&#x2F;h4&gt;
&lt;p&gt;The JSON representation of the application binary interface. See the
official
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;develop&#x2F;abi-spec.html&quot;&gt;specification&lt;&#x2F;a&gt;
for more information.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;address&quot;&gt;Address&lt;&#x2F;h4&gt;
&lt;p&gt;A public identifier for an account on a particular chain&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bytecode&quot;&gt;Bytecode&lt;&#x2F;h4&gt;
&lt;p&gt;The set of EVM instructions as produced by a compiler. Unless otherwise
specified this should be assumed to be hexadecimal encoded, representing
a whole number of bytes, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#prefixed&quot;&gt;prefixed&lt;&#x2F;a&gt; with &lt;code&gt;0x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Bytecode can either be linked or unlinked. (see
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#linking&quot;&gt;Linking&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unlinked Bytecode&lt;&#x2F;strong&gt;: The hexadecimal representation of a contract’s EVM instructions that contains sections of code that requires &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#linking&quot;&gt;linking&lt;&#x2F;a&gt; for the contract to be functional.&lt;br&gt;The sections of code which are unlinked &lt;strong&gt;must&lt;&#x2F;strong&gt; be filled in with zero bytes.&lt;br&gt;&lt;strong&gt;Example&lt;&#x2F;strong&gt;: &lt;code&gt;0x606060405260e06000730000000000000000000000000000000000000000634d536f&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Linked Bytecode&lt;&#x2F;strong&gt;: The hexadecimal representation of a contract’s EVM instructions which has had all &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link References&lt;&#x2F;a&gt; replaced with the desired &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-value&quot;&gt;Link Values&lt;&#x2F;a&gt;. &lt;strong&gt;Example&lt;&#x2F;strong&gt;: &lt;code&gt;0x606060405260e06000736fe36000604051602001526040518160e060020a634d536f&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;chain-definition&quot;&gt;Chain Definition&lt;&#x2F;h4&gt;
&lt;p&gt;This definition originates from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0122.mediawiki&quot;&gt;BIP122
URI&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A URI in the format &lt;code&gt;blockchain:&#x2F;&#x2F;&amp;lt;chain_id&amp;gt;&#x2F;block&#x2F;&amp;lt;block_hash&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;chain_id&lt;&#x2F;code&gt; is the unprefixed hexadecimal representation of the
genesis hash for the chain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;block_hash&lt;&#x2F;code&gt; is the unprefixed hexadecimal representation of the
hash of a block on the chain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A chain is considered to match a chain definition if the genesis
block hash matches the &lt;code&gt;chain_id&lt;&#x2F;code&gt; and the block defined by &lt;code&gt;block_hash&lt;&#x2F;code&gt;
can be found on that chain. It is possible for multiple chains to match
a single URI, in which case all chains are considered valid matches&lt;&#x2F;p&gt;
&lt;h4 id=&quot;content-addressable-uri&quot;&gt;Content Addressable URI&lt;&#x2F;h4&gt;
&lt;p&gt;Any URI which contains a cryptographic hash which can be used to verify
the integrity of the content found at the URI.&lt;&#x2F;p&gt;
&lt;p&gt;The URI format is defined in RFC3986&lt;&#x2F;p&gt;
&lt;p&gt;It is &lt;strong&gt;recommended&lt;&#x2F;strong&gt; that tools support IPFS and Swarm.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-alias&quot;&gt;Contract Alias&lt;&#x2F;h4&gt;
&lt;p&gt;This is a name used to reference a specific &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;. Contract aliases &lt;strong&gt;must&lt;&#x2F;strong&gt; be unique within a
single &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package&quot;&gt;Package&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The contract alias &lt;strong&gt;must&lt;&#x2F;strong&gt; use &lt;em&gt;one of&lt;&#x2F;em&gt; the following naming schemes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;contract-name&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;contract-name&amp;gt;&amp;lt;identifier&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;contract-name&amp;gt;&lt;&#x2F;code&gt; portion &lt;strong&gt;must&lt;&#x2F;strong&gt; be the same as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-name&quot;&gt;Contract
Name&lt;&#x2F;a&gt; for this contract type.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;identifier&amp;gt;&lt;&#x2F;code&gt; portion &lt;strong&gt;must&lt;&#x2F;strong&gt; match the regular expression
&lt;code&gt;^[-a-zA-Z0-9]{1,256}$&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-instance&quot;&gt;Contract Instance&lt;&#x2F;h4&gt;
&lt;p&gt;A contract instance a specific deployed version of a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;All contract instances have an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#address&quot;&gt;Address&lt;&#x2F;a&gt; on some specific
chain.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-instance-name&quot;&gt;Contract Instance Name&lt;&#x2F;h4&gt;
&lt;p&gt;A name which refers to a specific &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-instance&quot;&gt;Contract
Instance&lt;&#x2F;a&gt; on a specific chain from the
deployments of a single &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package&quot;&gt;Package&lt;&#x2F;a&gt;. This name &lt;strong&gt;must&lt;&#x2F;strong&gt; be
unique across all other contract instances for the given chain. The name
must conform to the regular expression
&lt;code&gt;^[a-zA-Z_$][a-zA-Z0-9_$]{0,255}$&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In cases where there is a single deployed instance of a given &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;, package managers &lt;strong&gt;should&lt;&#x2F;strong&gt; use the
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-alias&quot;&gt;Contract Alias&lt;&#x2F;a&gt; for that contract type for this
name.&lt;&#x2F;p&gt;
&lt;p&gt;In cases where there are multiple deployed instances of a given contract
type, package managers &lt;strong&gt;should&lt;&#x2F;strong&gt; use a name which provides some added
semantic information as to help differentiate the two deployed instances
in a meaningful way.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-name&quot;&gt;Contract Name&lt;&#x2F;h4&gt;
&lt;p&gt;The name found in the source code that defines a specific &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#contract-type&quot;&gt;Contract
Type&lt;&#x2F;a&gt;. These names &lt;strong&gt;must&lt;&#x2F;strong&gt; conform to the regular
expression &lt;code&gt;^[a-zA-Z_$][a-zA-Z0-9_$]{0,255}$&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There can be multiple contracts with the same contract name in a
projects source files.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contract-type&quot;&gt;Contract Type&lt;&#x2F;h4&gt;
&lt;p&gt;Refers to a specific contract in the package source. This term can be
used to refer to an abstract contract, a normal contract, or a library.
Two contracts are of the same contract type if they have the same
bytecode.&lt;&#x2F;p&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Wallet {&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;A deployed instance of the &lt;code&gt;Wallet&lt;&#x2F;code&gt; contract would be of of type
&lt;code&gt;Wallet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;identifier&quot;&gt;Identifier&lt;&#x2F;h4&gt;
&lt;p&gt;Refers generally to a named entity in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package&quot;&gt;Package&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A string matching the regular expression
&lt;code&gt;^[a-zA-Z][-_a-zA-Z0-9]{0,255}$&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;link-reference&quot;&gt;Link Reference&lt;&#x2F;h4&gt;
&lt;p&gt;A location within a contract’s bytecode which needs to be linked. A link
reference has the following properties.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;offset&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Defines the location within the bytecode where the link reference begins.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;length&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Defines the length of the reference.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: (optional) A string to identify the reference.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;link-value&quot;&gt;Link Value&lt;&#x2F;h4&gt;
&lt;p&gt;A link value is the value which can be inserted in place of a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link
Reference&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;linking&quot;&gt;Linking&lt;&#x2F;h4&gt;
&lt;p&gt;The act of replacing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-reference&quot;&gt;Link References&lt;&#x2F;a&gt; with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#link-value&quot;&gt;Link
Values&lt;&#x2F;a&gt; within some &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#bytecode&quot;&gt;Bytecode&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;package&quot;&gt;Package&lt;&#x2F;h4&gt;
&lt;p&gt;Distribution of an application’s source or compiled bytecode along with
metadata related to authorship, license, versioning, et al.&lt;&#x2F;p&gt;
&lt;p&gt;For brevity, the term &lt;strong&gt;Package&lt;&#x2F;strong&gt; is often used metonymously to mean
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#package-manifest&quot;&gt;Package Manifest&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;package-manifest&quot;&gt;Package Manifest&lt;&#x2F;h4&gt;
&lt;p&gt;A machine-readable description of a package.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;prefixed&quot;&gt;Prefixed&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#bytecode&quot;&gt;Bytecode&lt;&#x2F;a&gt; string with leading &lt;code&gt;0x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Example&lt;&#x2F;strong&gt;: &lt;code&gt;0xdeadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;unprefixed&quot;&gt;Unprefixed&lt;&#x2F;h4&gt;
&lt;p&gt;Not &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2678&#x2F;#prefixed&quot;&gt;Prefixed&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Example&lt;&#x2F;strong&gt;: &lt;code&gt;deadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;minification&quot;&gt;Minification&lt;&#x2F;h3&gt;
&lt;p&gt;EthPM packages are distributed as alphabetically-ordered &amp;amp; minified JSON to ensure consistency.
Since packages are published on content-addressable filesystems (eg. IPFS), this restriction
guarantees that any given set of contract assets will always resolve to the same content-addressed URI.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;package-names&quot;&gt;Package Names&lt;&#x2F;h3&gt;
&lt;p&gt;Package names are restricted to lower-case characters, numbers, and &lt;code&gt;-&lt;&#x2F;code&gt; to improve the readability
of the package name, in turn improving the security properties for a package. A user is more likely
to accurately identify their target package with this restricted set of characters, and not confuse
a malicious package that disguises itself as a trusted package with similar but different
characters (e.g. &lt;code&gt;O&lt;&#x2F;code&gt; and &lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bip122&quot;&gt;BIP122&lt;&#x2F;h3&gt;
&lt;p&gt;The BIP-122 standard has been used since EthPM v1 since it is an industry standard URI scheme for
identifying different blockchains and distinguishing between forks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compilers-1&quot;&gt;Compilers&lt;&#x2F;h3&gt;
&lt;p&gt;Compilers are now defined in a top-level array, simplifying the task for tooling to identify the compiler types
needed to interact with or validate the contract assets. This also removes unnecessarily duplicated
information, should multiple &lt;code&gt;contractTypes&lt;&#x2F;code&gt; share the same compiler type.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;To improve understanding and readability of the EthPM spec, the
&lt;code&gt;manifest_version&lt;&#x2F;code&gt; field was updated to &lt;code&gt;manifest&lt;&#x2F;code&gt; in v3. To ensure
backwards compatibility, v3 packages &lt;strong&gt;must&lt;&#x2F;strong&gt; define a top-level
&lt;code&gt;&quot;manifest&quot;&lt;&#x2F;code&gt; with a value of &lt;code&gt;&quot;ethpm&#x2F;3&quot;&lt;&#x2F;code&gt;. Additionally,
&lt;code&gt;&quot;manifest_version&quot;&lt;&#x2F;code&gt; is a forbidden top-level key in v3 packages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Using EthPM packages implicitly requires importing &amp;amp;&#x2F;or executing code written by others. The EthPM spec
guarantees that when using a properly constructed and released EthPM package, the user will have the exact same
code that was included in the package by the package author. However, it is impossible to guarantee that this code
is safe to interact with. Therefore, it is critical that end users only interact with EthPM packages authored and
released by individuals or organizations that they trust to include non-malicious code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Limit account nonce to 2^64-1</title>
        <published>2020-04-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2681/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2681-limit-account-nonce-to-2-64-1/4324" />
        

        <id>https://wg-eips.ritovision.com/2681/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2681"
            label="EIP-2681" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2681/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Limit account nonce to be between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;2^64-1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Account nonces are currently specified to be arbitrarily long unsigned integers. Dealing with arbitrary length data in the state witnesses is not optimal, therefore this EIP will allow proofs to represent the nonce in a more optimized way.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally it could prove beneficial to transaction formats, where some improvements are potentially sought by at least three other proposals.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, this facilitates a minor optimisation in clients, because the nonce no longer needs to be kept as a 256-bit number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce two new restrictions retroactively from genesis:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Consider any transaction invalid, where the nonce exceeds or equals to &lt;code&gt;2^64-1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; instructions&#x27; execution ends with the result &lt;code&gt;0&lt;&#x2F;code&gt; pushed on stack, where the account nonce is &lt;code&gt;2^64-1&lt;&#x2F;code&gt;. Gas for initcode execution is not deducted in this case.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It is unlikely for any nonce to reach or exceed the proposed limit. If one would want to reach that limit via external transactions, it would cost at least &lt;code&gt;21000 * (2^64-1) = 387_381_625_547_900_583_915_000&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It must be noted that in the past, in the Morden testnet, each new account had a starting nonce of &lt;code&gt;2^20&lt;&#x2F;code&gt; in order to differentiate transactions from mainnet transactions.
This mode of replay protection is out of fashion since &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; introduced a more elegant way using chain identifiers.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Most clients already consider the nonce field to be 64-bit, such as go-ethereum.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The reason a transaction with nonce &lt;code&gt;2^64-1&lt;&#x2F;code&gt; is invalid, because otherwise after inclusion the sender account&#x27;s nonce would exceed &lt;code&gt;2^64-1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;While this is a breaking change, no actual effect should be visible:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;There is no account in the state currently which would have a nonce exceeding that value. As of November 2020, the account &lt;code&gt;0xea674fdde714fd979de3edf0f56aa9716b898ec8&lt;&#x2F;code&gt; is responsible for the highest account nonce at approximately 29 million.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;go-ethereum already has this restriction partially in place (&lt;code&gt;state.Account.Nonce&lt;&#x2F;code&gt; and &lt;code&gt;types.txdata.AccountNonce&lt;&#x2F;code&gt; it as a 64-bit number).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Permit Extension for EIP-20 Signed Approvals</title>
        <published>2020-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:26+00:00</updated>
	
	
	<author>
		<name>Martin Lundfall</name><uri>https://github.com/Mrchico</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2612/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2613" />
        

        <id>https://wg-eips.ritovision.com/2612/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2612"
            label="ERC-2612" />
        

        
        

        
        <summary type="html">EIP-20 approvals via EIP-712 secp256k1 signatures</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2612/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Arguably one of the main reasons for the success of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;EIP-20&lt;&#x2F;a&gt; tokens lies in the interplay between &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, which allows for tokens to not only be transferred between externally owned accounts (EOA), but to be used in other contracts under application specific conditions by abstracting away &lt;code&gt;msg.sender&lt;&#x2F;code&gt; as the defining mechanism for token access control.&lt;&#x2F;p&gt;
&lt;p&gt;However, a limiting factor in this design stems from the fact that the EIP-20 &lt;code&gt;approve&lt;&#x2F;code&gt; function itself is defined in terms of &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. This means that user&#x27;s &lt;em&gt;initial action&lt;&#x2F;em&gt; involving EIP-20 tokens must be performed by an EOA (&lt;em&gt;but see Note below&lt;&#x2F;em&gt;). If the user needs to interact with a smart contract, then they need to make 2 transactions (&lt;code&gt;approve&lt;&#x2F;code&gt; and the smart contract call which will internally call &lt;code&gt;transferFrom&lt;&#x2F;code&gt;). Even in the simple use case of paying another person, they need to hold ETH to pay for transaction gas costs.&lt;&#x2F;p&gt;
&lt;p&gt;This ERC extends the EIP-20 standard with a new function &lt;code&gt;permit&lt;&#x2F;code&gt;, which allows users to modify the &lt;code&gt;allowance&lt;&#x2F;code&gt; mapping using a signed message, instead of through &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For an improved user experience, the signed data is structured following &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;, which already has wide spread adoption in major RPC providers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; EIP-20 must be performed by an EOA unless the address owning the token is actually a contract wallet. Although contract wallets solves many of the same problems that motivates this EIP, they are currently only scarcely adopted in the ecosystem. Contract wallets suffer from a UX problem -- since they separate the EOA &lt;code&gt;owner&lt;&#x2F;code&gt; of the contract wallet from the contract wallet itself (which is meant to carry out actions on the &lt;code&gt;owner&lt;&#x2F;code&gt;s behalf and holds all of their funds), user interfaces need to be specifically designed to support them. The &lt;code&gt;permit&lt;&#x2F;code&gt; pattern reaps many of the same benefits while requiring little to no change in user interfaces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;While EIP-20 tokens have become ubiquitous in the Ethereum ecosystem, their status remains that of second class tokens from the perspective of the protocol. The ability for users to interact with Ethereum without holding any ETH has been a long outstanding goal and the subject of many EIPs.&lt;&#x2F;p&gt;
&lt;p&gt;So far, many of these proposals have seen very little adoption, and the ones that have been adopted (such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;EIP-777&lt;&#x2F;a&gt;), introduce a lot of additional functionality, causing unexpected behavior in mainstream contracts.&lt;&#x2F;p&gt;
&lt;p&gt;This ERC proposes an alternative solution which is designed to be as minimal as possible and to only address &lt;em&gt;one problem&lt;&#x2F;em&gt;: the lack of abstraction in the EIP-20 &lt;code&gt;approve&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;While it may be tempting to introduce &lt;code&gt;*_by_signature&lt;&#x2F;code&gt; counterparts for every EIP-20 function, they are intentionally left out of this EIP-20 for two reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the desired specifics of such functions, such as decision regarding fees for &lt;code&gt;transfer_by_signature&lt;&#x2F;code&gt;, possible batching algorithms, varies depending on the use case, and,&lt;&#x2F;li&gt;
&lt;li&gt;they can be implemented using a combination of &lt;code&gt;permit&lt;&#x2F;code&gt; and additional helper contracts without loss of generality.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Compliant contracts must implement 3 new functions in addition to EIP-20:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; permit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; deadline&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; nonces&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-entity z-name&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&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 semantics of which are as follows:&lt;&#x2F;p&gt;
&lt;p&gt;For all addresses &lt;code&gt;owner&lt;&#x2F;code&gt;, &lt;code&gt;spender&lt;&#x2F;code&gt;, uint256s &lt;code&gt;value&lt;&#x2F;code&gt;, &lt;code&gt;deadline&lt;&#x2F;code&gt; and &lt;code&gt;nonce&lt;&#x2F;code&gt;, uint8 &lt;code&gt;v&lt;&#x2F;code&gt;, bytes32 &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt;,
a call to &lt;code&gt;permit(owner, spender, value, deadline, v, r, s)&lt;&#x2F;code&gt; will set
&lt;code&gt;allowance[owner][spender]&lt;&#x2F;code&gt; to &lt;code&gt;value&lt;&#x2F;code&gt;,
increment &lt;code&gt;nonces[owner]&lt;&#x2F;code&gt; by 1,
and emit a corresponding &lt;code&gt;Approval&lt;&#x2F;code&gt; event,
if and only if the following conditions are met:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The current blocktime is less than or equal to &lt;code&gt;deadline&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;owner&lt;&#x2F;code&gt; is not the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;nonces[owner]&lt;&#x2F;code&gt; (before the state update) is equal to &lt;code&gt;nonce&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; and &lt;code&gt;v&lt;&#x2F;code&gt; is a valid &lt;code&gt;secp256k1&lt;&#x2F;code&gt; signature from &lt;code&gt;owner&lt;&#x2F;code&gt; of the message:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If any of these conditions are not met, the &lt;code&gt;permit&lt;&#x2F;code&gt; call must revert.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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&gt;   hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;1901&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&gt;   DOMAIN_SEPARATOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;   keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&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&gt;            nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            deadline&lt;&#x2F;span&gt;&lt;span&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&gt;)&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;where &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; is defined according to EIP-712. The &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; should be unique to the contract and chain to prevent replay attacks from other domains,
and satisfy the requirements of EIP-712, but is otherwise unconstrained.
A common choice for &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DOMAIN_SEPARATOR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-variable z-language&quot;&gt;    abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;version&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;        chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&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 other words, the message is the EIP-712 typed structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;types&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP712Domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;verifyingContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Permit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;primaryType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Permit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; erc20name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; chainid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;verifyingContract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tokenAddress&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;deadline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; deadline&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;Note that nowhere in this definition we refer to &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. The caller of the &lt;code&gt;permit&lt;&#x2F;code&gt; function can be any address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;permit&lt;&#x2F;code&gt; function is sufficient for enabling any operation involving EIP-20 tokens to be paid for using the token itself, rather than using ETH.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;nonces&lt;&#x2F;code&gt; mapping is given for replay protection.&lt;&#x2F;p&gt;
&lt;p&gt;A common use case of &lt;code&gt;permit&lt;&#x2F;code&gt; has a relayer submit a &lt;code&gt;Permit&lt;&#x2F;code&gt; on behalf of the &lt;code&gt;owner&lt;&#x2F;code&gt;. In this scenario, the relaying party is essentially given a free option to submit or withhold the &lt;code&gt;Permit&lt;&#x2F;code&gt;. If this is a cause of concern, the &lt;code&gt;owner&lt;&#x2F;code&gt; can limit the time a &lt;code&gt;Permit&lt;&#x2F;code&gt; is valid for by setting &lt;code&gt;deadline&lt;&#x2F;code&gt; to a value in the near future. The &lt;code&gt;deadline&lt;&#x2F;code&gt; argument can be set to &lt;code&gt;uint(-1)&lt;&#x2F;code&gt; to create &lt;code&gt;Permit&lt;&#x2F;code&gt;s that effectively never expire.&lt;&#x2F;p&gt;
&lt;p&gt;EIP-712 typed messages are included because of its wide spread adoption in many wallet providers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are already a couple of &lt;code&gt;permit&lt;&#x2F;code&gt; functions in token contracts implemented in contracts in the wild, most notably the one introduced in the &lt;code&gt;dai.sol&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Its implementation differs slightly from the presentation here in that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;instead of taking a &lt;code&gt;value&lt;&#x2F;code&gt; argument, it takes a bool &lt;code&gt;allowed&lt;&#x2F;code&gt;, setting approval to 0 or &lt;code&gt;uint(-1)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;the &lt;code&gt;deadline&lt;&#x2F;code&gt; argument is instead called &lt;code&gt;expiry&lt;&#x2F;code&gt;. This is not just a syntactic change, as it effects the contents of the signed message.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is also an implementation in the token &lt;code&gt;Stake&lt;&#x2F;code&gt; (Ethereum address &lt;code&gt;0x0Ae055097C6d159879521C384F1D2123D1f195e6&lt;&#x2F;code&gt;) with the same ABI as &lt;code&gt;dai&lt;&#x2F;code&gt; but with different semantics: it lets users issue &quot;expiring approvals&quot;, that only allow &lt;code&gt;transferFrom&lt;&#x2F;code&gt; to occur while &lt;code&gt;expiry &amp;gt;= block.timestamp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The specification presented here is in line with the implementation in Uniswap V2.&lt;&#x2F;p&gt;
&lt;p&gt;The requirement to revert if the permit is invalid was added when the EIP was already widely deployed, but at the moment it was consistent with all found implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Though the signer of a &lt;code&gt;Permit&lt;&#x2F;code&gt; may have a certain party in mind to submit their transaction, another party can always front run this transaction and call &lt;code&gt;permit&lt;&#x2F;code&gt; before the intended party. The end result is the same for the &lt;code&gt;Permit&lt;&#x2F;code&gt; signer, however.&lt;&#x2F;p&gt;
&lt;p&gt;Since the ecrecover precompile fails silently and just returns the zero address as &lt;code&gt;signer&lt;&#x2F;code&gt; when given malformed messages, it is important to ensure &lt;code&gt;owner != address(0)&lt;&#x2F;code&gt; to avoid &lt;code&gt;permit&lt;&#x2F;code&gt; from creating an approval to spend &quot;zombie funds&quot; belong to the zero address.&lt;&#x2F;p&gt;
&lt;p&gt;Signed &lt;code&gt;Permit&lt;&#x2F;code&gt; messages are censorable. The relaying party can always choose to not submit the &lt;code&gt;Permit&lt;&#x2F;code&gt; after having received it, withholding the option to submit it. The &lt;code&gt;deadline&lt;&#x2F;code&gt; parameter is one mitigation to this. If the signing party holds ETH they can also just submit the &lt;code&gt;Permit&lt;&#x2F;code&gt; themselves, which can render previously signed &lt;code&gt;Permit&lt;&#x2F;code&gt;s invalid.&lt;&#x2F;p&gt;
&lt;p&gt;The standard EIP-20 race condition for approvals (SWC-114) applies to &lt;code&gt;permit&lt;&#x2F;code&gt; as well.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;DOMAIN_SEPARATOR&lt;&#x2F;code&gt; contains the &lt;code&gt;chainId&lt;&#x2F;code&gt; and is defined at contract deployment instead of reconstructed for every signature, there is a risk of possible replay attacks between chains in the event of a future chain split.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ModExp Gas Cost</title>
        <published>2020-03-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Kelly Olson</name><uri>https://github.com/ineffectualproperty</uri>
	</author>
	
	<author>
		<name>Sean Gulley</name><uri>https://github.com/sean-sn</uri>
	</author>
	
	<author>
		<name>Simon Peffers</name><uri>https://github.com/simonatsn</uri>
	</author>
	
	<author>
		<name>Justin Drake</name><uri>https://github.com/justindrake</uri>
	</author>
	
	<author>
		<name>Dankrad Feist</name><uri>https://github.com/dankrad</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2565/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/big-integer-modular-exponentiation-eip-198-gas-cost/4150" />
        

        <id>https://wg-eips.ritovision.com/2565/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2565"
            label="EIP-2565" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2565/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Defines the gas cost of the &lt;code&gt;ModExp&lt;&#x2F;code&gt; (&lt;code&gt;0x00..05&lt;&#x2F;code&gt;) precompile.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;To accurately reflect the real world operational cost of the &lt;code&gt;ModExp&lt;&#x2F;code&gt; precompile, this EIP specifies an algorithm for calculating the gas cost. This algorithm approximates the multiplication complexity cost and multiplies that by an approximation of the iterations required to execute the exponentiation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Modular exponentiation is a foundational arithmetic operation for many cryptographic functions including signatures, VDFs, SNARKs, accumulators, and more. Unfortunately, the ModExp precompile is currently over-priced, making these operations inefficient and expensive. By reducing the cost of this precompile, these cryptographic functions become more practical, enabling improved security, stronger randomness (VDFs), and more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;As of &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt;, the gas cost of calling the precompile at address &lt;code&gt;0x0000000000000000000000000000000000000005&lt;&#x2F;code&gt; will be calculated as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def calculate_multiplication_complexity(base_length, modulus_length):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    max_length = max(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    words = math.ceil(max_length &#x2F; 8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return words**2&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;def calculate_iteration_count(exponent_length, exponent):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    iteration_count = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if exponent_length &amp;lt;= 32 and exponent == 0: iteration_count = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;lt;= 32: iteration_count = exponent.bit_length() - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif exponent_length &amp;gt; 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent &amp;amp; (2**256 - 1)).bit_length() - 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(iteration_count, 1)&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;def calculate_gas_cost(base_length, modulus_length, exponent_length, exponent):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multiplication_complexity = calculate_multiplication_complexity(base_length, modulus_length)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    iteration_count = calculate_iteration_count(exponent_length, exponent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return max(200, math.floor(multiplication_complexity * iteration_count &#x2F; 3))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;After benchmarking the ModExp precompile, we discovered that it is ‘overpriced’ relative to other precompiles. We also discovered that the current gas pricing formula could be improved to better estimate the computational complexity of various ModExp input variables. The following changes improve the accuracy of the &lt;code&gt;ModExp&lt;&#x2F;code&gt; pricing:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-modify-computational-complexity-formula-to-better-reflect-the-computational-complexity&quot;&gt;1. Modify ‘computational complexity’ formula to better reflect the computational complexity&lt;&#x2F;h3&gt;
&lt;p&gt;The complexity function defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt; is as follow:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def mult_complexity(x):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if x &amp;lt;= 64: return x ** 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif x &amp;lt;= 1024: return x ** 2 &#x2F;&#x2F; 4 + 96 * x - 3072&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    else: return x ** 2 &#x2F;&#x2F; 16 + 480 * x - 199680&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where is &lt;code&gt;x&lt;&#x2F;code&gt; is &lt;code&gt;max(length_of_MODULUS, length_of_BASE)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The complexity formula in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt; was meant to approximate the difficulty of Karatsuba multiplication. However, we found a better approximation for modelling modular exponentiation. In the complexity formula defined in this EIP, &lt;code&gt;x&lt;&#x2F;code&gt; is divided by 8 to account for the number of limbs in multiprecision arithmetic. A comparison of the current ‘complexity’ function and the proposed function against the execution time can be seen below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2565&#x2F;.&#x2F;assets&#x2F;Complexity_Regression.png&quot; alt=&quot;Option 1 Graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The complexity function defined here has a better fit vs. the execution time when compared to the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt; complexity function. This better fit is because this complexity formula accounts for the use of binary exponentiation algorithms that are used by ‘bigint’ libraries for large exponents. You may also notice the regression line of the proposed complexity function bisects the test vector data points. This is because the run time varies depending on if the modulus is even or odd.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-change-the-value-of-gquaddivisor&quot;&gt;2. Change the value of GQUADDIVISOR&lt;&#x2F;h3&gt;
&lt;p&gt;After changing the &#x27;computational complexity&#x27; formula in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt; to the one defined here it is necessary to change &lt;code&gt;QGUADDIVSOR&lt;&#x2F;code&gt; to bring the gas costs inline with their runtime. By setting the &lt;code&gt;QGUADDIVISOR&lt;&#x2F;code&gt; to &lt;code&gt;3&lt;&#x2F;code&gt; the cost of the ModExp precompile will have a higher cost (gas&#x2F;second) than other precompiles such as ECRecover.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2565&#x2F;.&#x2F;assets&#x2F;GQuad_Change.png&quot; alt=&quot;Option 2 Graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-set-a-minimum-gas-cost-to-prevent-abuse&quot;&gt;3. Set a minimum gas cost to prevent abuse&lt;&#x2F;h3&gt;
&lt;p&gt;This prevents the precompile from underpricing small input values.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;There are no changes to the underlying interface or arithmetic algorithms, so the existing test vectors can be reused. Below is a table with the updated test vectors:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Test Case&lt;&#x2F;th&gt;&lt;th&gt;EIP-198 Pricing&lt;&#x2F;th&gt;&lt;th&gt;EIP-2565 Pricing&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_square&lt;&#x2F;td&gt;&lt;td&gt;204&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_qube&lt;&#x2F;td&gt;&lt;td&gt;204&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_1_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;3276&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_square&lt;&#x2F;td&gt;&lt;td&gt;665&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_qube&lt;&#x2F;td&gt;&lt;td&gt;665&lt;&#x2F;td&gt;&lt;td&gt;200&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_2_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;10649&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_square&lt;&#x2F;td&gt;&lt;td&gt;1894&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_qube&lt;&#x2F;td&gt;&lt;td&gt;1894&lt;&#x2F;td&gt;&lt;td&gt;341&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_3_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;30310&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_square&lt;&#x2F;td&gt;&lt;td&gt;5580&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_qube&lt;&#x2F;td&gt;&lt;td&gt;5580&lt;&#x2F;td&gt;&lt;td&gt;1365&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_4_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;89292&lt;&#x2F;td&gt;&lt;td&gt;21845&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_square&lt;&#x2F;td&gt;&lt;td&gt;17868&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_qube&lt;&#x2F;td&gt;&lt;td&gt;17868&lt;&#x2F;td&gt;&lt;td&gt;5461&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;modexp_nagydani_5_pow0x10001&lt;&#x2F;td&gt;&lt;td&gt;285900&lt;&#x2F;td&gt;&lt;td&gt;87381&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;implementations&quot;&gt;Implementations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;21607&quot;&gt;Geth&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;ineffectualproperty&#x2F;60e34f15c31850c5b60c8cf3a28cd423&quot;&gt;Python&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The biggest security consideration for this EIP is creating a potential DoS vector by making ModExp operations too inexpensive relative to their computation time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Diamonds, Multi-Facet Proxy</title>
        <published>2020-02-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Mudge</name><uri>https://github.com/mudgen</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2535/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/discussion-for-eip2535-diamonds/10459/" />
        

        <id>https://wg-eips.ritovision.com/2535/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2535"
            label="ERC-2535" />
        

        
        

        
        <summary type="html">Create modular smart contract systems that can be extended after deployment.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2535/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;img align=&quot;right&quot; src=&quot;.&#x2F;assets&#x2F;diamond.svg&quot; width=&quot;230&quot; height=&quot;230&quot; alt=&quot;Diamonds contract structure&quot;&gt;
&lt;p&gt;This proposal standardizes diamonds, which are modular smart contract systems that can be upgraded&#x2F;extended after deployment, and have virtually no size limit. More technically, a &lt;strong&gt;diamond&lt;&#x2F;strong&gt; is a contract with external functions that are supplied by contracts called &lt;strong&gt;facets&lt;&#x2F;strong&gt;. Facets are separate, independent contracts that can share internal functions, libraries, and state variables.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There are a number of different reasons to use diamonds. Here are some of them:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A single address for unlimited contract functionality.&lt;&#x2F;strong&gt; Using a single address for contract functionality makes deployment, testing and integration with other smart contracts, software and user interfaces easier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Your contract exceeds the 24KB maximum contract size.&lt;&#x2F;strong&gt; You may have related functionality that it makes sense to keep in a single contract, or at a single contract address. A diamond does not have a max contract size.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A diamond provides a way to organize contract code and data.&lt;&#x2F;strong&gt; You may want to build a contract system with a lot of functionality. A diamond provides a systematic way to isolate different functionality and connect them together and share data between them as needed in a gas-efficient way.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A diamond provides a way to upgrade functionality.&lt;&#x2F;strong&gt; Upgradeable diamonds can be upgraded to add&#x2F;replace&#x2F;remove functionality. Because diamonds have no max contract size, there is no limit to the amount of functionality that can be added to diamonds over time. Diamonds can be upgraded without having to redeploy existing functionality. Parts of a diamond can be added&#x2F;replaced&#x2F;removed while leaving other parts alone.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A diamond can be immutable.&lt;&#x2F;strong&gt; It is possible to deploy an immutable diamond or make an upgradeable diamond immutable at a later time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A diamond can reuse deployed contracts.&lt;&#x2F;strong&gt; Instead of deploying contracts to a blockchain, existing already deployed, onchain contracts can be used to create diamonds. Custom diamonds can be created from existing deployed contracts. This enables the creation of on-chain smart contract platforms and libraries.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This standard is an improvement of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1538&#x2F;&quot;&gt;EIP-1538&lt;&#x2F;a&gt;. The same motivations of that standard apply to this standard.&lt;&#x2F;p&gt;
&lt;p&gt;A deployed facet can be used by any number of diamonds.&lt;&#x2F;p&gt;
&lt;p&gt;The diagram below shows two diamonds using the same two facets.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FacetA&lt;&#x2F;code&gt; is used by &lt;code&gt;Diamond1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FacetA&lt;&#x2F;code&gt; is used by &lt;code&gt;Diamond2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FacetB&lt;&#x2F;code&gt; is used by &lt;code&gt;Diamond1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FacetB&lt;&#x2F;code&gt; is used by &lt;code&gt;Diamond2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;img src=&quot;.&#x2F;assets&#x2F;facetreuse.png&quot; alt=&quot;Facet reuse&quot;&gt;
&lt;h3 id=&quot;upgradeable-diamond-vs-centralized-private-database&quot;&gt;Upgradeable Diamond vs. Centralized Private Database&lt;&#x2F;h3&gt;
&lt;p&gt;Why have an upgradeable diamond instead of a centralized, private, mutable database?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Decentralized Autonomous Organizations (DAOs) and other governance systems can be used to upgrade diamonds.&lt;&#x2F;li&gt;
&lt;li&gt;Wide interaction and integration with the Ethereum ecosystem.&lt;&#x2F;li&gt;
&lt;li&gt;With open storage data and verified source code it is possible to show a provable history of trustworthiness.&lt;&#x2F;li&gt;
&lt;li&gt;With openness bad behavior can be spotted and reported when it happens.&lt;&#x2F;li&gt;
&lt;li&gt;Independent security and domain experts can review the change history of contracts and vouch for their history of trustworthiness.&lt;&#x2F;li&gt;
&lt;li&gt;It is possible for an upgradeable diamond to become immutable and trustless.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;some-diamond-benefits&quot;&gt;Some Diamond Benefits&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;A stable contract address that provides needed functionality.&lt;&#x2F;li&gt;
&lt;li&gt;A single address with the functionality of multiple contracts (facets) that are independent from each other but can share internal functions, libraries and state variables.&lt;&#x2F;li&gt;
&lt;li&gt;Emitting events from a single address can simplify event handling.&lt;&#x2F;li&gt;
&lt;li&gt;A way to add, replace and remove multiple external functions atomically (in the same transaction).&lt;&#x2F;li&gt;
&lt;li&gt;Fine-grained upgrades, so you can change just the parts of a diamond that need to be changed.&lt;&#x2F;li&gt;
&lt;li&gt;Have greater control over when and what functions exist.&lt;&#x2F;li&gt;
&lt;li&gt;Decentralized Autonomous Organizations (DAOs), multisig contracts and other governance systems can be used to upgrade diamonds.&lt;&#x2F;li&gt;
&lt;li&gt;An event that shows what functions are added, replaced and removed.&lt;&#x2F;li&gt;
&lt;li&gt;The ability to show all changes made to a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;Increase trust over time by showing all changes made to a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;A way to look at a diamond to see its current facets and functions.&lt;&#x2F;li&gt;
&lt;li&gt;Have an immutable, trustless diamond.&lt;&#x2F;li&gt;
&lt;li&gt;Solves the 24KB maximum contract size limitation. Diamonds can be any size.&lt;&#x2F;li&gt;
&lt;li&gt;Separate functionality can be implemented in separate facets and used together in a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;Diamonds can be created from already deployed, existing onchain contracts.&lt;&#x2F;li&gt;
&lt;li&gt;Larger contracts have to reduce their size by removing error messages and other things. You can keep your full functionality that you need by implementing a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;Enables zero, partial or full diamond immutability as desired, and when desired.&lt;&#x2F;li&gt;
&lt;li&gt;The ability to develop and improve an application over time with an upgradeable diamond and then make it immutable and trustless if desired.&lt;&#x2F;li&gt;
&lt;li&gt;Develop incrementally and let your diamond grow with your application.&lt;&#x2F;li&gt;
&lt;li&gt;Upgrade diamonds to fix bugs, add functionality and implement new standards.&lt;&#x2F;li&gt;
&lt;li&gt;Organize your code with a diamond and facets.&lt;&#x2F;li&gt;
&lt;li&gt;Diamonds can be large (have many functions) but still be modular because they are compartmented with facets.&lt;&#x2F;li&gt;
&lt;li&gt;Contract architectures that call multiple contracts in a single transaction can save gas by condensing those contracts into a single diamond and accessing state variables directly.&lt;&#x2F;li&gt;
&lt;li&gt;Save gas by converting external functions to internal functions. This done by sharing internal functions between facets.&lt;&#x2F;li&gt;
&lt;li&gt;Save gas by creating external functions for gas-optimized specific use cases, such as bulk transfers.&lt;&#x2F;li&gt;
&lt;li&gt;Diamonds are designed for tooling and user-interface software.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;terms&quot;&gt;Terms&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;diamond&lt;&#x2F;strong&gt; is a facade smart contract that &lt;code&gt;delegatecall&lt;&#x2F;code&gt;s into its facets to execute function calls. A diamond is stateful. Data is stored in the contract storage of a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;strong&gt;facet&lt;&#x2F;strong&gt; is a stateless smart contract or Solidity library with external functions. A facet is deployed and one or more of its functions are added to one or more diamonds. A facet does not store data within its own contract storage but it can define state and read and write to the storage of one or more diamonds. The term facet comes from the diamond industry. It is a side, or flat surface of a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;strong&gt;loupe facet&lt;&#x2F;strong&gt; is a facet that provides introspection functions. In the diamond industry, a loupe is a magnifying glass that is used to look at diamonds.&lt;&#x2F;li&gt;
&lt;li&gt;An &lt;strong&gt;immutable function&lt;&#x2F;strong&gt; is an external function that cannot be replaced or removed (because it is defined directly in the diamond, or because the diamond&#x27;s logic does not allow it to be modified).&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;strong&gt;mapping&lt;&#x2F;strong&gt; for the purposes of this EIP is an association between two things and does not refer to a specific implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The term &lt;strong&gt;contract&lt;&#x2F;strong&gt; is used loosely to mean a smart contract or deployed Solidity library.&lt;&#x2F;p&gt;
&lt;p&gt;When this EIP uses &lt;strong&gt;function&lt;&#x2F;strong&gt; without specifying internal or external, it means external function.&lt;&#x2F;p&gt;
&lt;p&gt;In this EIP the information that applies to external functions also applies to public functions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;A diamond calls functions from its facets using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the diamond industry diamonds are created and shaped by being cut, creating facets. In this standard diamonds are cut by adding, replacing or removing functions from facets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-note-on-implementing-interfaces&quot;&gt;A Note on Implementing Interfaces&lt;&#x2F;h3&gt;
&lt;p&gt;Because of the nature of diamonds, a diamond can implement an interface in one of two ways: directly (&lt;code&gt;contract Contract is Interface&lt;&#x2F;code&gt;), or by adding functions to it from one or more facets. For the purposes of this proposal, when a diamond is said to implement an interface, either method of implementation is permitted.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fallback-function&quot;&gt;Fallback Function&lt;&#x2F;h3&gt;
&lt;p&gt;When an external function is called on a diamond its fallback function is executed. The fallback function determines which facet to call based on the first four bytes of the call data (known as the function selector) and executes that function from the facet using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A diamond&#x27;s fallback function and &lt;code&gt;delegatecall&lt;&#x2F;code&gt; enable a diamond to execute a facet&#x27;s function as if it was implemented by the diamond itself. The &lt;code&gt;msg.sender&lt;&#x2F;code&gt; and &lt;code&gt;msg.value&lt;&#x2F;code&gt; values do not change and only the diamond&#x27;s storage is read and written to.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an illustrative example of how a diamond&#x27;s fallback function might be implemented:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find facet for function that is called and execute the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; function if a facet is found and return any value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get facet from function selector&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span&gt; facet &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; selectorTofacet&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sig&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;  require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;facet &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Execute external function from facet using delegatecall and return any value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; copy function selector and any arguments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; execute function call using the facet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; facet&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get any return value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    returndatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; return any return value or error back to the caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    switch result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      case &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;      default &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;This diagram shows the structure of a diamond:&lt;&#x2F;p&gt;
&lt;img src=&quot;.&#x2F;assets&#x2F;DiamondDiagram.png&quot; alt=&quot;Mapping facets and storage&quot;&gt;
&lt;h3 id=&quot;storage&quot;&gt;Storage&lt;&#x2F;h3&gt;
&lt;p&gt;A state variable or storage layout organizational pattern is needed because Solidity&#x27;s builtin storage layout system doesn&#x27;t support proxy contracts or diamonds. The particular layout of storage is not defined in this EIP, but may be defined by later proposals. Examples of storage layout patterns that work with diamonds are &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;.&#x2F;assets&#x2F;storage-examples&#x2F;DiamondStorage.sol&quot;&gt;Diamond Storage&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;.&#x2F;assets&#x2F;storage-examples&#x2F;AppStorage.sol&quot;&gt;AppStorage&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Facets can share state variables by using the same structs at the same storage positions. Facets can share internal functions and libraries by inheriting the same contracts or using the same libraries. In these ways facets are separate, independent units but can share state and functionality.&lt;&#x2F;p&gt;
&lt;p&gt;The diagram below shows facets with their own data and data shared between them.&lt;&#x2F;p&gt;
&lt;p&gt;Notice that all data is stored in the diamond&#x27;s storage, but different facets have different access to data.&lt;&#x2F;p&gt;
&lt;p&gt;In this diagram&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Only &lt;code&gt;FacetA&lt;&#x2F;code&gt; can access &lt;code&gt;DataA&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Only &lt;code&gt;FacetB&lt;&#x2F;code&gt; can access &lt;code&gt;DataB&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Only the diamond&#x27;s own code can access &lt;code&gt;DataD&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FacetA&lt;&#x2F;code&gt; and &lt;code&gt;FacetB&lt;&#x2F;code&gt; share access to &lt;code&gt;DataAB&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The diamond&#x27;s own code, &lt;code&gt;FacetA&lt;&#x2F;code&gt; and &lt;code&gt;FacetB&lt;&#x2F;code&gt; share access to &lt;code&gt;DataABD&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;img src=&quot;.&#x2F;assets&#x2F;diamondstorage1.png&quot; alt=&quot;Mapping code, data, and facets&quot;&gt;
&lt;h3 id=&quot;solidity-libraries-as-facets&quot;&gt;Solidity Libraries as Facets&lt;&#x2F;h3&gt;
&lt;p&gt;Smart contracts or deployed Solidity libraries can be facets of diamonds.&lt;&#x2F;p&gt;
&lt;p&gt;Only Solidity libraries that have one or more external functions can be deployed to a blockchain and be a facet.&lt;&#x2F;p&gt;
&lt;p&gt;Solidity libraries that contain internal functions only cannot be deployed and cannot be a facet. Internal functions from Solidity libraries are included in the bytecode of facets and contracts that use them. Solidity libraries with internal functions only are useful for sharing internal functions between facets.&lt;&#x2F;p&gt;
&lt;p&gt;Solidity library facets have a few properties that match their use as facets:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;They cannot be deleted.&lt;&#x2F;li&gt;
&lt;li&gt;They are stateless. They do not have contract storage.&lt;&#x2F;li&gt;
&lt;li&gt;Their syntax prevents declaring state variables outside Diamond Storage.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;adding-replacing-removing-functions&quot;&gt;Adding&#x2F;Replacing&#x2F;Removing Functions&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;idiamond-interface&quot;&gt;&lt;code&gt;IDiamond&lt;&#x2F;code&gt; Interface&lt;&#x2F;h4&gt;
&lt;p&gt;All diamonds must implement the &lt;code&gt;IDiamond&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;p&gt;During the deployment of a diamond any immutable functions and any external functions added to the diamond must be emitted in the &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;A &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event must be emitted any time external functions are added, replaced, or removed.&lt;&#x2F;strong&gt; This applies to all upgrades, all functions changes, at any time, whether through &lt;code&gt;diamondCut&lt;&#x2F;code&gt; or not.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDiamond&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FacetCutAction&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;Add&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Replace&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt; Remove&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add=0, Replace=1, Remove=2&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FacetCut&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; facetAddress&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        FacetCutAction action&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; functionSelectors&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DiamondCut&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;FacetCut&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _diamondCut&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _init&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _calldata&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event records all function changes to a diamond.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;idiamondcut-interface&quot;&gt;&lt;code&gt;IDiamondCut&lt;&#x2F;code&gt; Interface&lt;&#x2F;h4&gt;
&lt;p&gt;A diamond contains within it a mapping of function selectors to facet addresses. Functions are added&#x2F;replaced&#x2F;removed by modifying this mapping.&lt;&#x2F;p&gt;
&lt;p&gt;Diamonds should implement the &lt;code&gt;IDiamondCut&lt;&#x2F;code&gt; interface if after their deployment they allow modifications to their function selector mapping.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function updates any number of functions from any number of facets in a single transaction. Executing all changes within a single transaction prevents data corruption which could occur in upgrades done over multiple transactions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;diamondCut&lt;&#x2F;code&gt; is specified for the purpose of interoperability. Diamond tools, software and user-interfaces should expect and use the standard &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDiamondCut&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDiamond&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add&#x2F;replace&#x2F;remove any number of functions and optionally execute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         a function with delegatecall&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _diamondCut&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Contains the facet addresses and function selectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _init&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the contract or facet to execute _calldata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A function call, including function selector and arguments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  _calldata is executed with delegatecall on _init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; diamondCut&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        FacetCut&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _diamondCut&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _init&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _calldata&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;_diamondCut&lt;&#x2F;code&gt; argument is an array of &lt;code&gt;FacetCut&lt;&#x2F;code&gt; structs.&lt;&#x2F;p&gt;
&lt;p&gt;Each &lt;code&gt;FacetCut&lt;&#x2F;code&gt; struct contains a facet address and array of function selectors that are updated in a diamond.&lt;&#x2F;p&gt;
&lt;p&gt;For each &lt;code&gt;FacetCut&lt;&#x2F;code&gt; struct:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the &lt;code&gt;action&lt;&#x2F;code&gt; is &lt;code&gt;Add&lt;&#x2F;code&gt;, update the function selector mapping for each &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; item to the &lt;code&gt;facetAddress&lt;&#x2F;code&gt;. If any of the &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; had a mapped facet, revert instead.&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;action&lt;&#x2F;code&gt; is &lt;code&gt;Replace&lt;&#x2F;code&gt;, update the function selector mapping for each &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; item to the &lt;code&gt;facetAddress&lt;&#x2F;code&gt;. If any of the &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; had a value equal to &lt;code&gt;facetAddress&lt;&#x2F;code&gt; or the selector was unset, revert instead.&lt;&#x2F;li&gt;
&lt;li&gt;If the &lt;code&gt;action&lt;&#x2F;code&gt; is &lt;code&gt;Remove&lt;&#x2F;code&gt;, remove the function selector mapping for each &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; item. If any of the &lt;code&gt;functionSelectors&lt;&#x2F;code&gt; were previously unset, revert instead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Any attempt to replace or remove an immutable function must revert.&lt;&#x2F;p&gt;
&lt;p&gt;Being intentional and explicit about adding&#x2F;replacing&#x2F;removing functions helps catch and prevent upgrade mistakes.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;executing-calldata&quot;&gt;Executing &lt;code&gt;_calldata&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;p&gt;After adding&#x2F;replacing&#x2F;removing functions the &lt;code&gt;_calldata&lt;&#x2F;code&gt; argument is executed with &lt;code&gt;delegatecall&lt;&#x2F;code&gt; on &lt;code&gt;_init&lt;&#x2F;code&gt;. This execution is done to initialize data or setup or remove anything needed or no longer needed after adding, replacing and&#x2F;or removing functions.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;_init&lt;&#x2F;code&gt; value is &lt;code&gt;address(0)&lt;&#x2F;code&gt; then &lt;code&gt;_calldata&lt;&#x2F;code&gt; execution is skipped. In this case &lt;code&gt;_calldata&lt;&#x2F;code&gt; can contain 0 bytes or custom information.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inspecting-facets-functions&quot;&gt;Inspecting Facets &amp;amp; Functions&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A loupe is a small magnifying glass used to look at diamonds.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Diamonds must support inspecting facets and functions by implementing the &lt;code&gt;IDiamondLoupe&lt;&#x2F;code&gt; interface.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;idiamondloupe-interface&quot;&gt;&lt;code&gt;IDiamondLoupe&lt;&#x2F;code&gt; Interface&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A loupe is a small magnifying glass used to look at diamonds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; These functions look at diamonds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IDiamondLoupe&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Facet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; facetAddress&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; functionSelectors&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets all facet addresses and their four byte function selectors.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; facets_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Facet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; facets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Facet&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; facets_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets all the function selectors supported by a specific facet.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _facet&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The facet address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; facetFunctionSelectors_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; facetFunctionSelectors&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _facet&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; facetFunctionSelectors_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get all the facet addresses used by a diamond.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; facetAddresses_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; facetAddresses&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; facetAddresses_&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Gets the facet that supports the given selector.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If facet is not found return address(0).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _functionSelector&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The function selector.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; facetAddress_&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The facet address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; facetAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _functionSelector&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; facetAddress_&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;#reference-implementation&quot;&gt;reference implementation&lt;&#x2F;a&gt; to see how this can be implemented.&lt;&#x2F;p&gt;
&lt;p&gt;The loupe functions can be used in user-interface software. A user interface calls these functions to provide information about and visualize diamonds.&lt;&#x2F;p&gt;
&lt;p&gt;The loupe functions can be used in deployment functionality, upgrade functionality, testing and other software.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation-points&quot;&gt;Implementation Points&lt;&#x2F;h3&gt;
&lt;p&gt;A diamond must implement the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A diamond contains a fallback function and zero or more immutable functions that are defined within it.&lt;&#x2F;li&gt;
&lt;li&gt;A diamond associates function selectors with facets.&lt;&#x2F;li&gt;
&lt;li&gt;When a function is called on a diamond it executes immediately if it is an &quot;immutable function&quot; defined directly in the diamond. Otherwise the diamond&#x27;s fallback function is executed. The fallback function finds the facet associated with the function and executes the function using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;. If there is no facet for the function then optionally a default function may be executed. If there is no facet for the function and no default function and no other mechanism to handle it then execution reverts.&lt;&#x2F;li&gt;
&lt;li&gt;Each time functions are added, replaced or removed a &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event is emitted to record it.&lt;&#x2F;li&gt;
&lt;li&gt;A diamond implements the DiamondLoupe interface.&lt;&#x2F;li&gt;
&lt;li&gt;All immutable functions must be emitted in the &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event as new functions added. And the loupe functions must return information about immutable functions if they exist. The facet address for an immutable function is the diamond&#x27;s address. Any attempt to delete or replace an immutable function must revert.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A diamond may implement the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;supportsInterface&lt;&#x2F;code&gt;. If a diamond has the &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function then the interface ID used for it is &lt;code&gt;IDiamondCut.diamondCut.selector&lt;&#x2F;code&gt;. The interface ID used for the diamond loupe interface is &lt;code&gt;IDiamondLoupe.facets.selector ^ IDiamondLoupe.facetFunctionSelectors.selector ^ IDiamondLoupe.facetAddresses.selector ^ IDiamondLoupe.facetAddress.selector&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The diamond address is the address that users interact with. The diamond address does not change. Only facet addresses can change by using the &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function, or other function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;using-function-selectors&quot;&gt;Using Function Selectors&lt;&#x2F;h3&gt;
&lt;p&gt;User interface software can be used to retrieve function selectors and facet addresses from a diamond in order show what functions a diamond has.&lt;&#x2F;p&gt;
&lt;p&gt;This standard is designed to make diamonds work well with user-interface software. Function selectors with the ABI of a contract provide enough information about functions to be useful for user-interface software.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-considerations&quot;&gt;Gas Considerations&lt;&#x2F;h3&gt;
&lt;p&gt;Delegating function calls does have some gas overhead. This is mitigated in several ways:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Because diamonds do not have a max size limitation it is possible to add gas optimizing functions for use cases. For example someone could use a diamond to implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;EIP-721&lt;&#x2F;a&gt; standard and implement batch transfer functions to reduce gas (and make batch transfers more convenient).&lt;&#x2F;li&gt;
&lt;li&gt;Some contract architectures require calling multiple contracts in one transaction. Gas savings can be realized by condensing those contracts into a single diamond and accessing contract storage directly.&lt;&#x2F;li&gt;
&lt;li&gt;Facets can contain few external functions, reducing gas costs. Because it costs more gas to call a function in a contract with many functions than a contract with few functions.&lt;&#x2F;li&gt;
&lt;li&gt;The Solidity optimizer can be set to a high setting causing more bytecode to be generated but the facets will use less gas when executed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;versions-of-functions&quot;&gt;Versions of Functions&lt;&#x2F;h3&gt;
&lt;p&gt;Software or a user can verify what version of a function is called by getting the facet address of the function. This can be done by calling the &lt;code&gt;facetAddress&lt;&#x2F;code&gt; function from the &lt;code&gt;IDiamondLoupe&lt;&#x2F;code&gt; interface. This function takes a function selector as an argument and returns the facet address where it is implemented.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;default-function&quot;&gt;Default Function&lt;&#x2F;h3&gt;
&lt;p&gt;Solidity provides the &lt;code&gt;fallback&lt;&#x2F;code&gt; function so that specific functionality can be executed when a function is called on a contract that does not exist in the contract. This same behavior can optionally be implemented in a diamond by implementing and using a default function, which is a function that is executed when a function is called on a diamond that does not exist in the diamond.&lt;&#x2F;p&gt;
&lt;p&gt;A default function can be implemented a number of ways and this standard does not specify how it must be implemented.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;loupe-functions-diamondcut-event&quot;&gt;Loupe Functions &amp;amp; &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; Event&lt;&#x2F;h3&gt;
&lt;p&gt;To find out what functions a regular contract has it is only necessary to look at its verified source code.&lt;&#x2F;p&gt;
&lt;p&gt;The verified source code of a diamond does not include what functions it has so a different mechanism is needed.&lt;&#x2F;p&gt;
&lt;p&gt;A diamond has four standard functions called the loupe functions that are used to show what functions a diamond has.&lt;&#x2F;p&gt;
&lt;p&gt;The loupe functions can be used for many things including:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;To show all functions used by a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;To query services like Etherscan or files to retrieve and show all source code used by a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;To query services like Etherscan or files to retrieve ABI information for a diamond.&lt;&#x2F;li&gt;
&lt;li&gt;To test or verify that a transaction that adds&#x2F;replaces&#x2F;removes functions on a diamond succeeded.&lt;&#x2F;li&gt;
&lt;li&gt;To find out what functions a diamond has before calling functions on it.&lt;&#x2F;li&gt;
&lt;li&gt;To be used by tools and programming libraries to deploy and upgrade diamonds.&lt;&#x2F;li&gt;
&lt;li&gt;To be used by user interfaces to show information about diamonds.&lt;&#x2F;li&gt;
&lt;li&gt;To be used by user interfaces to enable users to call functions on diamonds.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Diamonds support another form of transparency which is a historical record of all upgrades on a diamond. This is done with the &lt;code&gt;DiamondCut&lt;&#x2F;code&gt; event which is used to record all functions that are added, replaced or removed on a diamond.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sharing-functions-between-facets&quot;&gt;Sharing Functions Between Facets&lt;&#x2F;h3&gt;
&lt;p&gt;In some cases it might be necessary to call a function defined in a different facet. Here are ways to do this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Copy internal function code in one facet to the other facet.&lt;&#x2F;li&gt;
&lt;li&gt;Put common internal functions in a contract that is inherited by multiple facets.&lt;&#x2F;li&gt;
&lt;li&gt;Put common internal functions in a Solidity library and use the library in facets.&lt;&#x2F;li&gt;
&lt;li&gt;A type safe way to call an external function defined in another facet is to do this: &lt;code&gt;MyOtherFacet(address(this)).myFunction(arg1, arg2)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A more gas-efficient way to call an external function defined in another facet is to use delegatecall. Here is an example of doing that:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DiamondStorage &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; ds &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; diamondStorage&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt; functionSelector &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;myFunction(uint256)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get facet address of function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; facet &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ds&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selectorToFacet&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;functionSelector&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; myFunctionCall &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;functionSelector&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&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&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;facet&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;myFunctionCall&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Instead of calling an external function defined in another facet you can instead create an internal function version of the external function. Add the internal version of the function to the facet that needs to use it.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;facets-can-be-reusable-and-composable&quot;&gt;Facets can be Reusable and Composable&lt;&#x2F;h3&gt;
&lt;p&gt;A deployed facet can be used by any number of diamonds.&lt;&#x2F;p&gt;
&lt;p&gt;Different combinations of facets can be used with different diamonds.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to create and deploy a set of facets that are reused by different diamonds over time.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to use the same deployed facets for many diamonds reduces deployment costs.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to implement facets in a way that makes them usable&#x2F;composable&#x2F;compatible with other facets. It is also possible to implement facets in a way that makes them not usable&#x2F;composable&#x2F;compatible with other facets.&lt;&#x2F;p&gt;
&lt;p&gt;A function signature is the name of a function and its parameter types. Example function signature: &lt;code&gt;myfunction(uint256)&lt;&#x2F;code&gt;. A limitation is that two external functions with the same function signature can’t be added to the same diamond at the same time because a diamond, or any contract, cannot have two external functions with the same function signature.&lt;&#x2F;p&gt;
&lt;p&gt;All the functions of a facet do not have to be added to a diamond. Some functions in a facet can be added to a diamond while other functions in the facet are not added to the diamond.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard makes upgradeable diamonds compatible with future standards and functionality because new functions can be added and existing functions can be replaced or removed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;All the Solidity code for a complete reference implementation has been put in a single file here: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;.&#x2F;assets&#x2F;reference&#x2F;Diamond.sol&quot;&gt;Diamond.sol&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The same reference implementation has been organized into multiple files and directories and also includes a deployment script and tests. Download it as a zip file: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;.&#x2F;assets&#x2F;reference&#x2F;EIP2535-Diamonds-Reference-Implementation.zip&quot;&gt;&lt;code&gt;EIP2535-Diamonds-Reference-Implementation.zip&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ownership-and-authentication&quot;&gt;Ownership and Authentication&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; The design and implementation of diamond ownership&#x2F;authentication is &lt;strong&gt;not&lt;&#x2F;strong&gt; part of this standard. The examples given in this standard and in the reference implementation are just &lt;strong&gt;examples&lt;&#x2F;strong&gt; of how it could be done.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It is possible to create many different authentication or ownership schemes with this proposal. Authentication schemes can be very simple or complex, fine grained or coarse. This proposal does not limit it in any way. For example ownership&#x2F;authentication could be as simple as a single account address having the authority to add&#x2F;replace&#x2F;remove functions. Or a decentralized autonomous organization could have the authority to only add&#x2F;replace&#x2F;remove certain functions.&lt;&#x2F;p&gt;
&lt;p&gt;Consensus functionality could be implemented such as an approval function that multiple different people call to approve changes before they are executed with the &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function. These are just examples.&lt;&#x2F;p&gt;
&lt;p&gt;The development of standards and implementations of ownership, control and authentication of diamonds is encouraged.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;arbitrary-execution-with-diamondcut&quot;&gt;Arbitrary Execution with &lt;code&gt;diamondCut&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function allows arbitrary execution with access to the diamond&#x27;s storage (through &lt;code&gt;delegatecall&lt;&#x2F;code&gt;). Access to this function must be restricted carefully.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;do-not-self-destruct&quot;&gt;Do Not Self Destruct&lt;&#x2F;h3&gt;
&lt;p&gt;Use of &lt;code&gt;selfdestruct&lt;&#x2F;code&gt; in a facet is heavily discouraged. Misuse of it can delete a diamond or a facet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;function-selector-clash&quot;&gt;Function Selector Clash&lt;&#x2F;h3&gt;
&lt;p&gt;A function selector clash occurs when two different function signatures hash to the same four-byte hash. This has the unintended consequence of replacing an existing function in a diamond when the intention was to add a new function. This scenario is not possible with a properly implemented &lt;code&gt;diamondCut&lt;&#x2F;code&gt; function because it prevents adding function selectors that already exist.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transparency&quot;&gt;Transparency&lt;&#x2F;h3&gt;
&lt;p&gt;Diamonds emit an event every time one or more functions are added, replaced or removed. All source code can be verified. This enables people and software to monitor changes to a contract. If any bad acting function is added to a diamond then it can be seen.&lt;&#x2F;p&gt;
&lt;p&gt;Security and domain experts can review the history of change of a diamond to detect any history of foul play.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Precompile for BLS12-381 curve operations</title>
        <published>2020-02-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Vlasov</name><uri>https://github.com/shamatar</uri>
	</author>
	
	<author>
		<name>Kelly Olson</name><uri>https://github.com/ineffectualproperty</uri>
	</author>
	
	<author>
		<name>Alex Stokes</name><uri>https://github.com/ralexstokes</uri>
	</author>
	
	<author>
		<name>Antonio Sanso</name><uri>https://github.com/asanso</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2537/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip2537-bls12-precompile-discussion-thread/4187" />
        

        <id>https://wg-eips.ritovision.com/2537/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2537"
            label="EIP-2537" />
        

        
        

        
        <summary type="html">Adds operation on BLS12-381 curve as a precompile in a set necessary to efficiently perform operations such as BLS signature verification.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2537/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Add functionality to efficiently perform operations over the BLS12-381 curve, including those for BLS signature verification.&lt;&#x2F;p&gt;
&lt;p&gt;Along with the curve arithmetic, multi-scalar-multiplication operations are included to efficiently aggregate public keys or individual signer&#x27;s signatures during BLS signature verification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The motivation of this precompile is to add a cryptographic primitive that allows to get 120+ bits of security for operations over pairing friendly curve compared to the existing BN254 precompile that only provides 80 bits of security.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constants&quot;&gt;Constants&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Comment&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;BLS12_G1ADD&lt;&#x2F;td&gt;&lt;td&gt;0x0b&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_G1MSM&lt;&#x2F;td&gt;&lt;td&gt;0x0c&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_G2ADD&lt;&#x2F;td&gt;&lt;td&gt;0x0d&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_G2MSM&lt;&#x2F;td&gt;&lt;td&gt;0x0e&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_PAIRING_CHECK&lt;&#x2F;td&gt;&lt;td&gt;0x0f&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_MAP_FP_TO_G1&lt;&#x2F;td&gt;&lt;td&gt;0x10&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BLS12_MAP_FP2_TO_G2&lt;&#x2F;td&gt;&lt;td&gt;0x11&lt;&#x2F;td&gt;&lt;td&gt;precompile address&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;We introduce &lt;em&gt;seven&lt;&#x2F;em&gt; separate precompiles to perform the following operations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;BLS12_G1ADD - to perform point addition in G1 (curve over base prime field) with a gas cost of &lt;code&gt;375&lt;&#x2F;code&gt; gas&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_G1MSM - to perform multi-scalar-multiplication (MSM) in G1 (curve over base prime field) with a gas cost formula defined in the corresponding section&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_G2ADD - to perform point addition in G2 (curve over quadratic extension of the base prime field) with a gas cost of &lt;code&gt;600&lt;&#x2F;code&gt; gas&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_G2MSM - to perform multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field) with a gas cost formula defined in the corresponding section&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_PAIRING_CHECK - to perform a pairing operations between a set of &lt;em&gt;pairs&lt;&#x2F;em&gt; of (G1, G2) points a gas cost formula defined in the corresponding section&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_MAP_FP_TO_G1 - maps base field element into the G1 point with a gas cost of &lt;code&gt;5500&lt;&#x2F;code&gt; gas&lt;&#x2F;li&gt;
&lt;li&gt;BLS12_MAP_FP2_TO_G2 - maps extension field element into the G2 point with a gas cost of &lt;code&gt;23800&lt;&#x2F;code&gt; gas&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A mapping functions specification is included as a separate &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;assets&#x2F;field_to_curve&#x2F;&quot;&gt;document&lt;&#x2F;a&gt;. This mapping function does NOT perform mapping of the byte string into a field element (as it can be implemented in many different ways and can be efficiently performed in EVM), but only does field arithmetic to map a field element into a curve point. Such functionality is required for signature schemes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;curve-parameters&quot;&gt;Curve parameters&lt;&#x2F;h3&gt;
&lt;p&gt;The BLS12 curve is fully defined by the following set of parameters (coefficient &lt;code&gt;A=0&lt;&#x2F;code&gt; for all BLS12 curves):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Base field modulus = p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp - finite field of size p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Curve Fp equation: Y^2 = X^3+B (mod p)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Main subgroup order = q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Extension tower&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp2 construction:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp quadratic non-residue = nr2 = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp2 is Fp[X]&#x2F;(X^2-nr2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Curve Fp2 equation: Y^2 = X^3 + B*(v+1) where v is the square root of nr2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp6&#x2F;Fp12 construction:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp2 cubic non-residue c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fp2 cubic non-residue c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Twist parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Twist type: M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;B coefficient for twist c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;B coefficient for twist c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Generators:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;H1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;H2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X c0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X c1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Y c0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Y c1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pairing parameters:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|x| (miller loop scalar) = 0xd201000000010000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x is negative = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One should note that base field modulus &lt;code&gt;p&lt;&#x2F;code&gt; is equal to &lt;code&gt;3 mod 4&lt;&#x2F;code&gt; that allows an efficient square root extraction, although as described below gas cost of decompression is larger than gas cost of supplying decompressed point data in &lt;code&gt;calldata&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fields-and-groups&quot;&gt;Fields and Groups&lt;&#x2F;h3&gt;
&lt;p&gt;Field Fp is defined as the finite field of size &lt;code&gt;p&lt;&#x2F;code&gt; with elements represented as integers between 0 and p-1 (both inclusive).&lt;&#x2F;p&gt;
&lt;p&gt;Field Fp2 is defined as &lt;code&gt;Fp[X]&#x2F;(X^2-nr2)&lt;&#x2F;code&gt; with elements  &lt;code&gt;el = c0 + c1 * v&lt;&#x2F;code&gt;, where &lt;code&gt;v&lt;&#x2F;code&gt; is the formal square root of &lt;code&gt;nr2&lt;&#x2F;code&gt; represented as integer pairs &lt;code&gt;(c0,c1)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Group G1 is defined as a set of Fp pairs (points) &lt;code&gt;(x,y)&lt;&#x2F;code&gt; such that either &lt;code&gt;(x,y)&lt;&#x2F;code&gt; is  &lt;code&gt;(0,0)&lt;&#x2F;code&gt; or &lt;code&gt;x,y&lt;&#x2F;code&gt; satisfy the curve Fp equation.&lt;&#x2F;p&gt;
&lt;p&gt;Group G2 is defined as a set of Fp2 pairs (points) &lt;code&gt;(x&#x27;,y&#x27;)&lt;&#x2F;code&gt; such that either &lt;code&gt;(x,y)&lt;&#x2F;code&gt; is &lt;code&gt;(0,0)&lt;&#x2F;code&gt; or &lt;code&gt;(x&#x27;,y&#x27;)&lt;&#x2F;code&gt; satisfy the curve Fp2 equation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fine-points-and-encoding-of-base-elements&quot;&gt;Fine points and encoding of base elements&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;field-elements-encoding&quot;&gt;Field elements encoding:&lt;&#x2F;h4&gt;
&lt;p&gt;In order to produce inputs to an operation, one encodes elements of the base field and the extension field.&lt;&#x2F;p&gt;
&lt;p&gt;A base field element (Fp) is encoded as &lt;code&gt;64&lt;&#x2F;code&gt; bytes by performing the BigEndian encoding of the corresponding (unsigned) integer. Due to the size of &lt;code&gt;p&lt;&#x2F;code&gt;, the top &lt;code&gt;16&lt;&#x2F;code&gt; bytes are always zeroes. &lt;code&gt;64&lt;&#x2F;code&gt; bytes are chosen to have &lt;code&gt;32&lt;&#x2F;code&gt; byte aligned ABI (representable as e.g. &lt;code&gt;bytes32[2]&lt;&#x2F;code&gt; or &lt;code&gt;uint256[2]&lt;&#x2F;code&gt; with the latter assuming the BigEndian encoding). The corresponding integer &lt;strong&gt;must&lt;&#x2F;strong&gt; be less than field modulus.&lt;&#x2F;p&gt;
&lt;p&gt;For elements of the quadratic extension field (Fp2), encoding is byte concatenation of individual encoding of the coefficients totaling in &lt;code&gt;128&lt;&#x2F;code&gt; bytes for a total encoding. For an Fp2 element in a form &lt;code&gt;el = c0 + c1 * v&lt;&#x2F;code&gt; where &lt;code&gt;v&lt;&#x2F;code&gt; is the formal square root of a quadratic non-residue and &lt;code&gt;c0&lt;&#x2F;code&gt; and &lt;code&gt;c1&lt;&#x2F;code&gt; are Fp elements the corresponding byte encoding will be &lt;code&gt;encode(c0) || encode(c1)&lt;&#x2F;code&gt; where &lt;code&gt;||&lt;&#x2F;code&gt; means byte concatenation (or one can use &lt;code&gt;bytes32[4]&lt;&#x2F;code&gt; or &lt;code&gt;uint256[4]&lt;&#x2F;code&gt; in terms of Solidity types).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note on the top &lt;code&gt;16&lt;&#x2F;code&gt; bytes being zero&lt;&#x2F;em&gt;: it is required that an encoded element is &quot;in a field&quot;, which means strictly &lt;code&gt;&amp;lt; modulus&lt;&#x2F;code&gt;. In BigEndian encoding it automatically means that for a modulus that is just &lt;code&gt;381&lt;&#x2F;code&gt; bit long the top &lt;code&gt;16&lt;&#x2F;code&gt; bytes in &lt;code&gt;64&lt;&#x2F;code&gt; bytes encoding are zeroes and this &lt;strong&gt;must&lt;&#x2F;strong&gt; be checked even if only a subslice of input data is used for actual decoding.&lt;&#x2F;p&gt;
&lt;p&gt;On inputs that can not be a valid encodings of field elements the precompile &lt;em&gt;must&lt;&#x2F;em&gt; return an error.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;encoding-of-points-in-g1-g2&quot;&gt;Encoding of points in G1&#x2F;G2:&lt;&#x2F;h4&gt;
&lt;p&gt;Points of G1 and G2 are encoded as byte concatenation of the respective encodings of the &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; coordinates. Total encoding length for a G1 point is thus &lt;code&gt;128&lt;&#x2F;code&gt; bytes and for a G2 point is &lt;code&gt;256&lt;&#x2F;code&gt; bytes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;point-of-infinity-encoding&quot;&gt;Point of infinity encoding:&lt;&#x2F;h4&gt;
&lt;p&gt;Also referred to as the &quot;zero point&quot;. For BLS12 curves, the point with coordinates &lt;code&gt;(0, 0)&lt;&#x2F;code&gt; (zeroes in Fp or Fp2) is &lt;em&gt;not&lt;&#x2F;em&gt; on the curve, so a sequence of &lt;code&gt;128&lt;&#x2F;code&gt; resp. &lt;code&gt;256&lt;&#x2F;code&gt; zero bytes, which naively would decode as &lt;code&gt;(0, 0)&lt;&#x2F;code&gt; is instead used by convention to encode the point of infinity of G1 resp. G2.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;encoding-of-scalars-for-multiplication-operation&quot;&gt;Encoding of scalars for multiplication operation:&lt;&#x2F;h4&gt;
&lt;p&gt;A scalar for the multiplication operation is encoded as &lt;code&gt;32&lt;&#x2F;code&gt; bytes by performing BigEndian encoding of the corresponding (unsigned) integer. The corresponding integer is &lt;strong&gt;not&lt;&#x2F;strong&gt; required to be less than or equal to main subgroup order &lt;code&gt;q&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;behavior-on-empty-inputs&quot;&gt;Behavior on empty inputs:&lt;&#x2F;h4&gt;
&lt;p&gt;Certain operations have variable length input, such as MSMs (takes a list of pairs &lt;code&gt;(point, scalar)&lt;&#x2F;code&gt;), or pairing (takes a list of &lt;code&gt;(G1, G2)&lt;&#x2F;code&gt; points). While their behavior is well-defined (from an arithmetic perspective) on empty inputs, this EIP discourages such use cases and variable input length operations must return an error if the input is empty.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;abi-for-operations&quot;&gt;ABI for operations&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;abi-for-g1-addition&quot;&gt;ABI for G1 addition&lt;&#x2F;h4&gt;
&lt;p&gt;G1 addition call expects &lt;code&gt;256&lt;&#x2F;code&gt; bytes as an input that is interpreted as byte concatenation of two G1 points (&lt;code&gt;128&lt;&#x2F;code&gt; bytes each). Output is an encoding of addition operation result - single G1 point (&lt;code&gt;128&lt;&#x2F;code&gt; bytes).&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid coordinate encoding&lt;&#x2F;li&gt;
&lt;li&gt;An input is neither a point on the G1 elliptic curve nor the infinity point&lt;&#x2F;li&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note:&lt;&#x2F;p&gt;
&lt;p&gt;There is no subgroup check for the G1 addition precompile.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;abi-for-g1-msm&quot;&gt;ABI for G1 MSM&lt;&#x2F;h4&gt;
&lt;p&gt;G1 MSM call expects &lt;code&gt;160*k&lt;&#x2F;code&gt; (&lt;code&gt;k&lt;&#x2F;code&gt; being a &lt;strong&gt;positive&lt;&#x2F;strong&gt; integer) bytes as an input that is interpreted as byte concatenation of &lt;code&gt;k&lt;&#x2F;code&gt; slices each of them being a byte concatenation of encoding of a G1 point (&lt;code&gt;128&lt;&#x2F;code&gt; bytes) and encoding of a scalar value (&lt;code&gt;32&lt;&#x2F;code&gt; bytes). Output is an encoding of MSM operation result - a single G1 point (&lt;code&gt;128&lt;&#x2F;code&gt; bytes).&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid coordinate encoding&lt;&#x2F;li&gt;
&lt;li&gt;An input is neither a point on the G1 elliptic curve nor the infinity point&lt;&#x2F;li&gt;
&lt;li&gt;An input is on the G1 elliptic curve but not in the correct subgroup&lt;&#x2F;li&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;abi-for-g2-addition&quot;&gt;ABI for G2 addition&lt;&#x2F;h4&gt;
&lt;p&gt;G2 addition call expects &lt;code&gt;512&lt;&#x2F;code&gt; bytes as an input that is interpreted as byte concatenation of two G2 points (&lt;code&gt;256&lt;&#x2F;code&gt; bytes each). Output is an encoding of addition operation result - a single G2 point (&lt;code&gt;256&lt;&#x2F;code&gt; bytes).&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid coordinate encoding&lt;&#x2F;li&gt;
&lt;li&gt;An input is neither a point on the G2 elliptic curve nor the infinity point&lt;&#x2F;li&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note:&lt;&#x2F;p&gt;
&lt;p&gt;There is no subgroup check for the G2 addition precompile.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;abi-for-g2-msm&quot;&gt;ABI for G2 MSM&lt;&#x2F;h4&gt;
&lt;p&gt;G2 MSM call expects &lt;code&gt;288*k&lt;&#x2F;code&gt; (&lt;code&gt;k&lt;&#x2F;code&gt; being a &lt;strong&gt;positive&lt;&#x2F;strong&gt; integer) bytes as an input that is interpreted as byte concatenation of &lt;code&gt;k&lt;&#x2F;code&gt; slices each of them being a byte concatenation of encoding of G2 point (&lt;code&gt;256&lt;&#x2F;code&gt; bytes) and encoding of a scalar value (&lt;code&gt;32&lt;&#x2F;code&gt; bytes). Output is an encoding of MSM operation result - a single G2 point (&lt;code&gt;256&lt;&#x2F;code&gt; bytes).&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid coordinate encoding&lt;&#x2F;li&gt;
&lt;li&gt;An input is neither a point on the G2 elliptic curve nor the infinity point&lt;&#x2F;li&gt;
&lt;li&gt;An input is on the G2 elliptic curve but not in the correct subgroup&lt;&#x2F;li&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;abi-for-pairing-check&quot;&gt;ABI for pairing check&lt;&#x2F;h4&gt;
&lt;p&gt;Pairing check call expects &lt;code&gt;384*k&lt;&#x2F;code&gt;  (&lt;code&gt;k&lt;&#x2F;code&gt; being a &lt;strong&gt;positive&lt;&#x2F;strong&gt; integer)  bytes as an inputs that is interpreted as byte concatenation of &lt;code&gt;k&lt;&#x2F;code&gt; slices. Each slice has the following structure:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;128&lt;&#x2F;code&gt; bytes of G1 point encoding&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;256&lt;&#x2F;code&gt; bytes of G2 point encoding&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each point is expected to be in the subgroup of order &lt;code&gt;q&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It checks the equation &lt;code&gt;e(P1, Q1) * e(P2, Q2) * ... * e(Pk, Qk) == 1&lt;&#x2F;code&gt; in the pairing target field where &lt;code&gt;e&lt;&#x2F;code&gt; is the pairing operation. Output is &lt;code&gt;32&lt;&#x2F;code&gt; bytes where first &lt;code&gt;31&lt;&#x2F;code&gt; bytes are equal to &lt;code&gt;0x00&lt;&#x2F;code&gt; and the last byte is either &lt;code&gt;0x00&lt;&#x2F;code&gt; (false) or &lt;code&gt;0x01&lt;&#x2F;code&gt; (true).&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Invalid coordinate encoding&lt;&#x2F;li&gt;
&lt;li&gt;An input is neither a point on its respective elliptic curve nor the infinity point&lt;&#x2F;li&gt;
&lt;li&gt;An input is on its respective elliptic curve but not in the correct subgroup&lt;&#x2F;li&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;abi-for-mapping-fp-element-to-g1-point&quot;&gt;ABI for mapping Fp element to G1 point&lt;&#x2F;h4&gt;
&lt;p&gt;Field-to-curve call expects &lt;code&gt;64&lt;&#x2F;code&gt; bytes as an input that is interpreted as an element of Fp. Output of this call is &lt;code&gt;128&lt;&#x2F;code&gt; bytes and is an encoded G1 point.&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;li&gt;Input is not correctly encoded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;abi-for-mapping-fp2-element-to-g2-point&quot;&gt;ABI for mapping Fp2 element to G2 point&lt;&#x2F;h4&gt;
&lt;p&gt;Field-to-curve call expects &lt;code&gt;128&lt;&#x2F;code&gt; bytes as an input that is interpreted as an element of Fp2. Output of this call is &lt;code&gt;256&lt;&#x2F;code&gt; bytes and is an encoded G2 point.&lt;&#x2F;p&gt;
&lt;p&gt;Error cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Input has invalid length&lt;&#x2F;li&gt;
&lt;li&gt;Input is not correctly encoded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;gas-burning-on-error&quot;&gt;Gas burning on error&lt;&#x2F;h3&gt;
&lt;p&gt;Following the current state of all other precompiles, if a call to one of the precompiles in this EIP results in an error then all the gas supplied along with a &lt;code&gt;CALL&lt;&#x2F;code&gt; or &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; is burned.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ddos-protection&quot;&gt;DDoS protection&lt;&#x2F;h3&gt;
&lt;p&gt;A sane implementation of this EIP &lt;em&gt;should not&lt;&#x2F;em&gt; contain potential infinite loops (it is possible and not even hard to implement all the functionality without &lt;code&gt;while&lt;&#x2F;code&gt; loops) and the gas schedule accurately reflects the time spent on computations of the corresponding function (precompiles pricing reflects an amount of gas consumed in the worst case where such a case exists).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-schedule&quot;&gt;Gas schedule&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming &lt;code&gt;EcRecover&lt;&#x2F;code&gt; precompile as a baseline.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;g1-addition&quot;&gt;G1 addition&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;375&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h4 id=&quot;g1-multiplication&quot;&gt;G1 multiplication&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;12000&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h4 id=&quot;g2-addition&quot;&gt;G2 addition&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;600&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h4 id=&quot;g2-multiplication&quot;&gt;G2 multiplication&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;22500&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h4 id=&quot;g1-g2-msm&quot;&gt;G1&#x2F;G2 MSM&lt;&#x2F;h4&gt;
&lt;p&gt;MSMs are expected to be performed by Pippenger&#x27;s algorithm (we can also say that it &lt;strong&gt;must&lt;&#x2F;strong&gt; be performed by Pippenger&#x27;s algorithm to have a speedup that results in a discount over naive implementation by multiplying each pair separately and adding the results). For this case there was a table prepared for discount in case of &lt;code&gt;k &amp;lt;= 128&lt;&#x2F;code&gt; points in the MSM with a discount cap &lt;code&gt;max_discount&lt;&#x2F;code&gt; for &lt;code&gt;k &amp;gt; 128&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The call cost is calculated as &lt;code&gt;(k * multiplication_cost * discount) &#x2F;&#x2F; multiplier&lt;&#x2F;code&gt; where &lt;code&gt;multiplier = 1000&lt;&#x2F;code&gt;, &lt;code&gt;k&lt;&#x2F;code&gt; is a number of (scalar, point) pairs for the call, &lt;code&gt;multiplication_cost&lt;&#x2F;code&gt; is a corresponding G1&#x2F;G2 multiplication cost presented above and &lt;code&gt;&#x2F;&#x2F;&lt;&#x2F;code&gt; is an integer division.&lt;&#x2F;p&gt;
&lt;p&gt;G1 and G2 are priced separately, each having their own discount table and &lt;code&gt;max_discount&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;g1-discounts&quot;&gt;G1 discounts&lt;&#x2F;h5&gt;
&lt;p&gt;Discounts table for G1 MSM as a vector of pairs &lt;code&gt;[k, discount]&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[1, 1000], [2, 949], [3, 848], [4, 797], [5, 764], [6, 750], [7, 738], [8, 728], [9, 719], [10, 712], [11, 705], [12, 698], [13, 692], [14, 687], [15, 682], [16, 677], [17, 673], [18, 669], [19, 665], [20, 661], [21, 658], [22, 654], [23, 651], [24, 648], [25, 645], [26, 642], [27, 640], [28, 637], [29, 635], [30, 632], [31, 630], [32, 627], [33, 625], [34, 623], [35, 621], [36, 619], [37, 617], [38, 615], [39, 613], [40, 611], [41, 609], [42, 608], [43, 606], [44, 604], [45, 603], [46, 601], [47, 599], [48, 598], [49, 596], [50, 595], [51, 593], [52, 592], [53, 591], [54, 589], [55, 588], [56, 586], [57, 585], [58, 584], [59, 582], [60, 581], [61, 580], [62, 579], [63, 577], [64, 576], [65, 575], [66, 574], [67, 573], [68, 572], [69, 570], [70, 569], [71, 568], [72, 567], [73, 566], [74, 565], [75, 564], [76, 563], [77, 562], [78, 561], [79, 560], [80, 559], [81, 558], [82, 557], [83, 556], [84, 555], [85, 554], [86, 553], [87, 552], [88, 551], [89, 550], [90, 549], [91, 548], [92, 547], [93, 547], [94, 546], [95, 545], [96, 544], [97, 543], [98, 542], [99, 541], [100, 540], [101, 540], [102, 539], [103, 538], [104, 537], [105, 536], [106, 536], [107, 535], [108, 534], [109, 533], [110, 532], [111, 532], [112, 531], [113, 530], [114, 529], [115, 528], [116, 528], [117, 527], [118, 526], [119, 525], [120, 525], [121, 524], [122, 523], [123, 522], [124, 522], [125, 521], [126, 520], [127, 520], [128, 519]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;max_discount = 519&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h5 id=&quot;g2-discounts&quot;&gt;G2 discounts&lt;&#x2F;h5&gt;
&lt;p&gt;Discounts table for G2 MSM as a vector of pairs &lt;code&gt;[k, discount]&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[1, 1000], [2, 1000], [3, 923], [4, 884], [5, 855], [6, 832], [7, 812], [8, 796], [9, 782], [10, 770], [11, 759], [12, 749], [13, 740], [14, 732], [15, 724], [16, 717], [17, 711], [18, 704], [19, 699], [20, 693], [21, 688], [22, 683], [23, 679], [24, 674], [25, 670], [26, 666], [27, 663], [28, 659], [29, 655], [30, 652], [31, 649], [32, 646], [33, 643], [34, 640], [35, 637], [36, 634], [37, 632], [38, 629], [39, 627], [40, 624], [41, 622], [42, 620], [43, 618], [44, 615], [45, 613], [46, 611], [47, 609], [48, 607], [49, 606], [50, 604], [51, 602], [52, 600], [53, 598], [54, 597], [55, 595], [56, 593], [57, 592], [58, 590], [59, 589], [60, 587], [61, 586], [62, 584], [63, 583], [64, 582], [65, 580], [66, 579], [67, 578], [68, 576], [69, 575], [70, 574], [71, 573], [72, 571], [73, 570], [74, 569], [75, 568], [76, 567], [77, 566], [78, 565], [79, 563], [80, 562], [81, 561], [82, 560], [83, 559], [84, 558], [85, 557], [86, 556], [87, 555], [88, 554], [89, 553], [90, 552], [91, 552], [92, 551], [93, 550], [94, 549], [95, 548], [96, 547], [97, 546], [98, 545], [99, 545], [100, 544], [101, 543], [102, 542], [103, 541], [104, 541], [105, 540], [106, 539], [107, 538], [108, 537], [109, 537], [110, 536], [111, 535], [112, 535], [113, 534], [114, 533], [115, 532], [116, 532], [117, 531], [118, 530], [119, 530], [120, 529], [121, 528], [122, 528], [123, 527], [124, 526], [125, 526], [126, 525], [127, 524], [128, 524]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;max_discount = 524&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;pairing-check-operation&quot;&gt;Pairing check operation&lt;&#x2F;h4&gt;
&lt;p&gt;The cost of the pairing check operation is &lt;code&gt;32600*k + 37700&lt;&#x2F;code&gt; where &lt;code&gt;k&lt;&#x2F;code&gt; is a number of pairs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;fp-to-g1-mapping-operation&quot;&gt;Fp-to-G1 mapping operation&lt;&#x2F;h4&gt;
&lt;p&gt;Fp -&amp;gt; G1 mapping is &lt;code&gt;5500&lt;&#x2F;code&gt; gas.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;fp2-to-g2-mapping-operation&quot;&gt;Fp2-to-G2 mapping operation&lt;&#x2F;h4&gt;
&lt;p&gt;Fp2 -&amp;gt; G2 mapping is &lt;code&gt;23800&lt;&#x2F;code&gt; gas&lt;&#x2F;p&gt;
&lt;h4 id=&quot;gas-schedule-clarifications-for-the-variable-length-input&quot;&gt;Gas schedule clarifications for the variable-length input&lt;&#x2F;h4&gt;
&lt;p&gt;For MSM and pairing functions, the gas cost depends on the input length. The current state of how the gas schedule is implemented in major clients (at the time of writing) is that the gas cost function does &lt;em&gt;not&lt;&#x2F;em&gt; perform any validation of the length of the input and never returns an error. So we present a list of rules how the gas cost functions &lt;strong&gt;must&lt;&#x2F;strong&gt; be implemented to ensure consistency between clients and safety.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;gas-schedule-clarifications-for-g1-g2-msm&quot;&gt;Gas schedule clarifications for G1&#x2F;G2 MSM&lt;&#x2F;h5&gt;
&lt;p&gt;Define a constant &lt;code&gt;LEN_PER_PAIR&lt;&#x2F;code&gt; that is equal to &lt;code&gt;160&lt;&#x2F;code&gt; for G1 operation and to &lt;code&gt;288&lt;&#x2F;code&gt; for G2 operation. Define a function &lt;code&gt;discount(k)&lt;&#x2F;code&gt; following the rules in the corresponding section, where &lt;code&gt;k&lt;&#x2F;code&gt; is number of pairs.&lt;&#x2F;p&gt;
&lt;p&gt;The following pseudofunction reflects how gas should be calculated:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;k = floor(len(input) &#x2F; LEN_PER_PAIR);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if k == 0 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  return 0;&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;gas_cost = k * multiplication_cost * discount(k) &#x2F;&#x2F; multiplier;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return gas_cost;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We use floor division to get the number of pairs. If the length of the input is not divisible by &lt;code&gt;LEN_PER_PAIR&lt;&#x2F;code&gt; we still produce &lt;em&gt;some&lt;&#x2F;em&gt; result, but later on the precompile will return an error. Also, the case when &lt;code&gt;k = 0&lt;&#x2F;code&gt; is safe: &lt;code&gt;CALL&lt;&#x2F;code&gt; or &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; cost is non-zero, and the case with formal zero gas cost is already used in &lt;code&gt;Blake2f&lt;&#x2F;code&gt; precompile. In any case, the main precompile routine &lt;strong&gt;must&lt;&#x2F;strong&gt; produce an error on such an input because it violated encoding rules.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;gas-schedule-clarifications-for-pairing&quot;&gt;Gas schedule clarifications for pairing&lt;&#x2F;h5&gt;
&lt;p&gt;Define a constant &lt;code&gt;LEN_PER_PAIR = 384&lt;&#x2F;code&gt;;&lt;&#x2F;p&gt;
&lt;p&gt;The following pseudofunction reflects how gas should be calculated:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;k = floor(len(input) &#x2F; LEN_PER_PAIR);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gas_cost = 32600*k + 37700;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return gas_cost;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We use floor division to get the number of pairs. If the length of the input is not divisible by &lt;code&gt;LEN_PER_PAIR&lt;&#x2F;code&gt; we still produce &lt;em&gt;some&lt;&#x2F;em&gt; result, but later on the precompile will return an error (the precompile routine &lt;strong&gt;must&lt;&#x2F;strong&gt; produce an error on such an input because it violated encoding rules).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The motivation section covers a total motivation to have operations over the BLS12-381 curves available. We also extend a rationale for more specific fine points.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;msm-as-a-separate-call&quot;&gt;MSM as a separate call&lt;&#x2F;h3&gt;
&lt;p&gt;Explicit separate MSM operation that allows one to save execution time (so gas) by both the algorithm used (namely Pippenger&#x27;s algorithm) and (usually forgotten) by the fact that &lt;code&gt;CALL&lt;&#x2F;code&gt; operation in Ethereum is expensive (at the time of writing), so one would have to pay non-negligible overhead if e.g. for MSM of &lt;code&gt;100&lt;&#x2F;code&gt; points would have to call the multiplication precompile &lt;code&gt;100&lt;&#x2F;code&gt; times and addition for &lt;code&gt;99&lt;&#x2F;code&gt; times (roughly &lt;code&gt;138600&lt;&#x2F;code&gt; would be saved).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;no-dedicated-mul-call&quot;&gt;No dedicated MUL call&lt;&#x2F;h3&gt;
&lt;p&gt;Dedicated MUL precompiles which perform single G1&#x2F;G2 point by scalar multiplication have exactly the same ABI as MSM with &lt;code&gt;k == 1&lt;&#x2F;code&gt;.
MSM has to inspect the input length to reject inputs of invalid lengths. Therefore, it should recognize the case of &lt;code&gt;k == 1&lt;&#x2F;code&gt; and invoke the underlying implementation of single point multiplication to avoid the overhead of more complex multi-scalar multiplication algorithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no backward compatibility questions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;subgroup-checks&quot;&gt;Subgroup checks&lt;&#x2F;h3&gt;
&lt;p&gt;MSMs and pairings MUST perform a subgroup check.
Implementations SHOULD use the optimized subgroup check method detailed in a dedicated &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;assets&#x2F;fast_subgroup_checks&#x2F;&quot;&gt;document&lt;&#x2F;a&gt;.
On any input that fails the subgroup check, the precompile MUST return an error.
As endomorphism acceleration requires input on the correct subgroup, implementers MAY use endomorphism acceleration.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;field-to-curve-mapping&quot;&gt;Field to curve mapping&lt;&#x2F;h3&gt;
&lt;p&gt;The algorithms and set of parameters for SWU mapping method are provided by a separate &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;assets&#x2F;field_to_curve&#x2F;&quot;&gt;document&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Due to the large test parameters space, we first provide properties that various operations must satisfy. We use additive notation for point operations, capital letters (&lt;code&gt;P&lt;&#x2F;code&gt;, &lt;code&gt;Q&lt;&#x2F;code&gt;) for points, small letters (&lt;code&gt;a&lt;&#x2F;code&gt;, &lt;code&gt;b&lt;&#x2F;code&gt;) for scalars. The generator for G1 is labeled as &lt;code&gt;G&lt;&#x2F;code&gt;, the generator for G2 is labeled as &lt;code&gt;H&lt;&#x2F;code&gt;, otherwise we assume random points on a curve in a correct subgroup. &lt;code&gt;0&lt;&#x2F;code&gt; means either scalar zero or point at infinity. &lt;code&gt;1&lt;&#x2F;code&gt; means either scalar one or multiplicative identity. &lt;code&gt;group_order&lt;&#x2F;code&gt; is the main subgroup order. &lt;code&gt;e(P, Q)&lt;&#x2F;code&gt; means pairing operation where &lt;code&gt;P&lt;&#x2F;code&gt; is in G1, &lt;code&gt;Q&lt;&#x2F;code&gt; is in G2.&lt;&#x2F;p&gt;
&lt;p&gt;Required properties for basic ops (add&#x2F;multiply):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Commutativity: &lt;code&gt;P + Q = Q + P&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Identity element: &lt;code&gt;P + 0 = P&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Additive negation: &lt;code&gt;P + (-P) = 0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Doubling &lt;code&gt;P + P = 2*P&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Subgroup check: &lt;code&gt;group_order * P = 0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Trivial multiplication check: &lt;code&gt;1 * P = P&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Multiplication by zero: &lt;code&gt;0 * P = 0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Multiplication by the unnormalized scalar &lt;code&gt;(scalar + group_order) * P = scalar * P&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Required properties for pairing operation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bilinearity &lt;code&gt;e(a*P, b*Q) = e(a*b*P, Q) = e(P, a*b*Q)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Non-degeneracy &lt;code&gt;e(P, Q) != 1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;e(P, 0*Q) = e(0*P, Q) = 1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;e(P, -Q) = e(-P, Q)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Test vectors can be found &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;assets&#x2F;test-vectors&#x2F;&quot;&gt;in the test vectors files&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;benchmarking-test-cases&quot;&gt;Benchmarking test cases&lt;&#x2F;h3&gt;
&lt;p&gt;A set of test vectors for quick benchmarking on new implementations is located in a separate &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2537&#x2F;assets&#x2F;bench_vectors&#x2F;&quot;&gt;file&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;There are two fully spec compatible implementations on the day of writing:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;One in Rust language that is based on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;196&#x2F;&quot;&gt;EIP-196&lt;&#x2F;a&gt; code and integrated with OpenEthereum for this library&lt;&#x2F;li&gt;
&lt;li&gt;One implemented specifically for Geth as a part of the current codebase&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Strictly following the spec will eliminate security implications or consensus implications in a contrast to the previous BN254 precompile.&lt;&#x2F;p&gt;
&lt;p&gt;Important topic is a &quot;constant time&quot; property for performed operations. We explicitly state that this precompile &lt;strong&gt;IS NOT REQUIRED&lt;&#x2F;strong&gt; to perform all the operations using constant time algorithms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>eth&#x2F;66 request identifier</title>
        <published>2020-01-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Christoph Burgdorf</name><uri>https://github.com/cburgdorf</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2481/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2481-eth-66-request-identifiers/12132" />
        

        <id>https://wg-eips.ritovision.com/2481/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        

        
        <category
            term="tag:eip:2481"
            label="EIP-2481" />
        

        
        

        
        <summary type="html">Introduces a request id for all requests of the eth protocol</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2481/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;eth&lt;&#x2F;code&gt; protocol defines various request and response commands that are used to exchange data between Ethereum nodes. For example, to ask a peer node for a specific set of headers, a node sends it the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;eth.md#getblockheaders-0x03&quot;&gt;&lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; command.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Citing from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;eth.md#getblockheaders-0x03&quot;&gt;&lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt; spec definition&lt;&#x2F;a&gt;:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;[block: {P, B_32}, maxHeaders: P, skip: P, reverse: P in {0, 1}]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Require peer to return a &lt;code&gt;BlockHeaders&lt;&#x2F;code&gt; message. Reply must contain a number of block
headers, of rising number when &lt;code&gt;reverse&lt;&#x2F;code&gt; is &lt;code&gt;0&lt;&#x2F;code&gt;, falling when &lt;code&gt;1&lt;&#x2F;code&gt;, &lt;code&gt;skip&lt;&#x2F;code&gt; blocks apart,
beginning at block &lt;code&gt;block&lt;&#x2F;code&gt; (denoted by either number or hash) in the canonical chain, and
with at most &lt;code&gt;maxHeaders&lt;&#x2F;code&gt; items.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The node that receives the &lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt; command should answer it with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;eth.md#blockheaders-0x04&quot;&gt;&lt;code&gt;BlockHeaders&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; response command accordingly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Citing from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&#x2F;blob&#x2F;40ab248bf7e017e83cc9812a4e048446709623e8&#x2F;caps&#x2F;eth.md#blockheaders-0x04&quot;&gt;&lt;code&gt;BlockHeaders&lt;&#x2F;code&gt; spec definition&lt;&#x2F;a&gt;:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;[blockHeader_0, blockHeader_1, ...]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Reply to &lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt;. The items in the list (following the message ID) are block
headers in the format described in the main Ethereum specification, previously asked for
in a GetBlockHeaders message. This may validly contain no block headers if none of the
requested block headers were found. The number of headers that can be requested in a
single message may be subject to implementation-defined limits.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Let&#x27;s consider a client making many simultaneous requests for &lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt; to one of its peers. By nature it can not be guaranteed that the expected responses arrive in the same order as they were sent. For the client to associate the incoming responses to the correct requests it has to loop through all pending requests trying to match it with the incoming response based on its contents.&lt;&#x2F;p&gt;
&lt;p&gt;This can be particular tricky for responses that are ambiguous such as empty responses.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP proposes to change the &lt;code&gt;GetBlockHeaders&lt;&#x2F;code&gt; and the &lt;code&gt;BlockHeaders&lt;&#x2F;code&gt; command to include a &lt;code&gt;request_id&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;request_id&lt;&#x2F;code&gt; is a 64-bit integer set by the client when it makes the request. On the responding side, the exact same &lt;code&gt;request_id&lt;&#x2F;code&gt; from the incoming request is put back into the response object.&lt;&#x2F;p&gt;
&lt;p&gt;This change allows the requesting client to match incoming responses &lt;strong&gt;directly&lt;&#x2F;strong&gt; back to their pending requests without going through all of the pending requests to check if they might match based on the response data.&lt;&#x2F;p&gt;
&lt;p&gt;The selected request&#x2F;response pair serves as an example for many similar request&#x2F;response pairs in the &lt;code&gt;eth&lt;&#x2F;code&gt; networking protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The lack of request identifiers in the request &#x2F; response paris of the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol puts unnecessary burden of code complexity into every Ethereum client. It also makes the communication slightly less efficient. Another argument can be made that the addition of request identifiers makes the protocol more aligned with the &lt;code&gt;les&lt;&#x2F;code&gt; protocol which &lt;strong&gt;does&lt;&#x2F;strong&gt; already defines request identifiers for each request &#x2F; response pair.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Change the following message types in the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GetBlockHeaders (0x03)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[block: {P, B_32}, maxHeaders: P, skip: P, reverse: P in {0, 1}]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [block: {P, B_32}, maxHeaders: P, skip: P, reverse: P in {0, 1}]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;BlockHeaders (0x04)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[blockHeader_0, blockHeader_1, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [blockHeader_0, blockHeader_1, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GetBlockBodies (0x05)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65)&lt;&#x2F;strong&gt;&lt;code&gt;[hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;&lt;code&gt;[request_id: P, [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65)&lt;&#x2F;strong&gt;&lt;code&gt;[[nonce: P, receivingAddress: B_20, value: P, ...], ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;&lt;code&gt;[request_id: P, [[nonce: P, receivingAddress: B_20, value: P, ...], ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;BlockBodies (0x06)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GetNodeData (0x0d)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [hash_0: B_32, hash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NodeData (0x0e)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[value_0: B, value_1: B, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [value_0: B, value_1: B, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GetReceipts (0x0f)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[blockHash_0: B_32, blockHash_1: B_32, ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [blockHash_0: B_32, blockHash_1: B_32, ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Receipts (0x10)&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current (eth&#x2F;65):&lt;&#x2F;strong&gt; &lt;code&gt;[[receipt_0, receipt_1], ...]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Then (eth&#x2F;66)&lt;&#x2F;strong&gt;: &lt;code&gt;[request_id: P, [[receipt_0, receipt_1], ...]]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To elaborate, each command is altered in the following way:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create a list with the &lt;code&gt;request_id&lt;&#x2F;code&gt; being the first element.&lt;&#x2F;li&gt;
&lt;li&gt;Make the second element the list that defines the whole command in the current scheme.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;code&gt;request_id&lt;&#x2F;code&gt; has the following characteristics:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;64 bit integer&lt;&#x2F;li&gt;
&lt;li&gt;Doesn&#x27;t need to be sequential (can be random)&lt;&#x2F;li&gt;
&lt;li&gt;Does allow duplicates&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Q: The efficiency gains might encourage clients to flood their peers with too many simultaneous requests&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Peers can always throttle or disconnect if they don&#x27;t feel treated well. This is the same as today.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: If &lt;code&gt;les&lt;&#x2F;code&gt; already defines the commands like this, why not just use the &lt;code&gt;les&lt;&#x2F;code&gt; protocol?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In practice, peers that serve the &lt;code&gt;les&lt;&#x2F;code&gt; protocol are much harder to find in the network. The reasons for this are varied but might boil down to client defaults, immature implementations or missing incentives.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Networking works today, isn&#x27;t this just adding bloat?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is adding a single integer per command while at the same time reducing code complexity and improving networking efficiency. The addition seems justified.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Why not demand request ids to be sequential?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assuming request ids start always to count from &lt;code&gt;0&lt;&#x2F;code&gt; upon connection, things will become messy when
connections are lost and clients reconnect and start over with the same request ids that they had used
in the previous session.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Why allow duplicate request ids?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The main benefit is flexibility and simplicity on the implementation side. Clients could decide to share
the same ids across multiple different request types since they are naturally separated anyway. Clients
could even decide to not rely on request ids at all, therefore using the same constant request id across
all requests.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Why choose a 64-bit integer for the request ids&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;64-bit integer were chosen to keep compatibility with the &lt;code&gt;les&lt;&#x2F;code&gt; protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP extends the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol in a backwards incompatible way and requires rolling out a new version, &lt;code&gt;eth&#x2F;66&lt;&#x2F;code&gt;. However, &lt;code&gt;devp2p&lt;&#x2F;code&gt; supports running multiple versions of the same wire protocol side-by-side, so rolling out &lt;code&gt;eth&#x2F;66&lt;&#x2F;code&gt; does not require client coordination, since non-updated clients can keep using &lt;code&gt;eth&#x2F;65&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change the consensus engine, thus does &lt;em&gt;not&lt;&#x2F;em&gt; require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;These testcases cover RLP-encoding of all the redefined messages types, where the &lt;code&gt;rlp&lt;&#x2F;code&gt; portion is the rlp-encoding of the message defined in the &lt;code&gt;data&lt;&#x2F;code&gt; portion.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetBlockHeadersPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xe8820457e4a000000000000000000000000000000000000000000000000000000000deadc0de050580&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Skip&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Reverse&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetBlockHeadersPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xca820457c682270f050580&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Number&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9999&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Skip&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Reverse&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;BlockHeadersPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BlockHeadersPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;parentHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sha3Uncles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;miner&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionsRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;receiptsRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logsBloom&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8ae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd05&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasLimit&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x115c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x15b3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1a0a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;extraData&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x7788&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;mixHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8c2f2af15b7b563b6ab1e09bed0e9caade7ed730aec98b70a993597a797579a9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetBlockBodiesPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;GetBlockBodiesPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;BlockBodiesPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;BlockBodiesPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Transactions&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4a817c808&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x2e248&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3535353535353535353535353535353535353535&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x25&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x588df025c4c2d757d3e314bd3dfbfe352687324e6b8557ad1731585e96928aed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4a817c809&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x33450&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3535353535353535353535353535353535353535&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x2d9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x25&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf39c7dac06a9f3abf09faf5e30439a349d3717611b3ed337cd52b0d192bc72da&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Uncles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;parentHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sha3Uncles&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;miner&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionsRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;receiptsRoot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logsBloom&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8ae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xd05&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasLimit&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x115c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x15b3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1a0a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;extraData&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x7788&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;mixHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8c2f2af15b7b563b6ab1e09bed0e9caade7ed730aec98b70a993597a797579a9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetNodeDataPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;GetNodeDataPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;NodeDataPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xce820457ca84deadc0de84feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;NodeDataPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdeadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xfeedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetReceiptsPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;GetReceiptsPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ReceiptsPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;ReceiptsPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;root&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;cumulativeGasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logsBloom&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000011&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000000000000000000000000dead&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x000000000000000000000000000000000000000000000000000000000000beef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0100ff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blockNumber&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blockHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;logIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;removed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;contractAddress&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000011111&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasUsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1b207&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;blockHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;transactionIndex&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GetPooledTransactionsPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;GetPooledTransactionsPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000deadc0de&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x00000000000000000000000000000000000000000000000000000000feedbeef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PooledTransactionsPacket66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;RequestId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;PooledTransactionsPacket&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4a817c808&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x2e248&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3535353535353535353535353535353535353535&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x25&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x588df025c4c2d757d3e314bd3dfbfe352687324e6b8557ad1731585e96928aed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gasPrice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4a817c809&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x33450&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;to&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3535353535353535353535353535353535353535&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x2d9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x25&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xf39c7dac06a9f3abf09faf5e30439a349d3717611b3ed337cd52b0d192bc72da&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;eth&#x2F;65: transaction announcements and retrievals&quot;</title>
        <published>2020-01-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Péter Szilágyi</name><email>peterke@gmail.com</email>
	</author>
	
	<author>
		<name>Péter Szilágyi</name><uri>https://github.com/karalabe</uri>
	</author>
	
	<author>
		<name>Gary Rong</name><email>garyrong0905@gmail.com</email>
	</author>
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2464/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2465" />
        

        <id>https://wg-eips.ritovision.com/2464/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2464"
            label="EIP-2464" />
        

        
        

        
        <summary type="html">Introduces `NewPooledTransactionHashes`, `GetPooledTransactions`, and `PooledTransactions`.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2464/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces three additional message types into the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol (releasing a new version, &lt;code&gt;eth&#x2F;65&lt;&#x2F;code&gt;): &lt;code&gt;NewPooledTransactionHashes (0x08)&lt;&#x2F;code&gt; to announce a set of transactions without their content; &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt; to request a batch of transactions by their announced hash; and &lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt; to reply to a transaction request. This permits reducing the bandwidth used for transaction propagation from linear complexity in the number of peers to square root; and also reducing the initial transaction exchange from 10s-100s MB to &lt;code&gt;len(pool) * 32B ~= 128KB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;eth&lt;&#x2F;code&gt; network protocol has two ways to propagate a newly mined block: it can be broadcast to a peer in its entirety (via &lt;code&gt;NewBlock (0x07)&lt;&#x2F;code&gt; in &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; and prior or it can be announced only (via &lt;code&gt;NewBlockHashes (0x01)&lt;&#x2F;code&gt;). This duality allows nodes to do the high-bandwidth broadcasting (10s-100s KB) for a square root number of peers; and the low-bandwidth announcing (10s-100s B) for the remaining linear number of peers. The square root broadcast is enough to reach all well connected nodes, but the linear announce is needed to get across degenerate topologies. This works well.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;eth&lt;&#x2F;code&gt; protocol, however, does not have a similar dual mechanism for propagating transactions, so nodes need to rely on broadcasting (via &lt;code&gt;Transactions (0x02)&lt;&#x2F;code&gt;). To cater for degenerate topologies, transactions cannot be broadcast square rooted, rather they need to be transferred linearly to all peers. With N peers, each node will transfer the same transaction N times (counting both directions), whereas 1 would be enough in a perfect world. This is a significant waste.&lt;&#x2F;p&gt;
&lt;p&gt;A similar issue arises when a new network connection is made between two nodes, as they need to sync up their transaction pools, but the pool is just a soup of dangling transactions. Without a way to deduplicate transactions remotely, each node is forced to naively transfer their entire list of transactions to the other side. With pools containing thousands of transactions, a naive transfer amounts to 10s-100s MB, most of which is useless. There is no better way, however.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP introduces three additional message types into the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol (releasing a new version, &lt;code&gt;eth&#x2F;65&lt;&#x2F;code&gt;): &lt;code&gt;NewPooledTransactionHashes (0x08)&lt;&#x2F;code&gt; to announce a set of transactions without their content; &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt; to request a batch of transactions by their announced hash; and &lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt; to reply to a transaction request. This permits reducing the bandwidth used for transaction propagation from linear complexity in the number of peers to square root; and also reducing the initial transaction exchange from 10s-100s MB to &lt;code&gt;len(pool) * 32B ~= 128KB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With transaction throughput (and size) picking up in Ethereum, transaction propagation is the current dominant component of the used network resources. Most of these resources are however wasted, as the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol does not have a mechanism to deduplicate transactions remotely, so the same data is transferred over and over again across all network connections.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP proposes a tiny extension to the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol, which permits nodes to agree on the set of transactions that need to be transferred across a network connection, before doing the costly exchange. This should help reduce the global (operational) bandwidth usage of the Ethereum network by at least an order of magnitude.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Add three new message types to the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NewPooledTransactionHashes (0x08): [hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Specify one or more transactions that have appeared in the network and which have &lt;strong&gt;not yet been included in a block&lt;&#x2F;strong&gt;. To be maximally helpful, nodes should inform peers of all transactions that they may not be aware of.&lt;&#x2F;li&gt;
&lt;li&gt;There is &lt;strong&gt;no protocol violating hard cap&lt;&#x2F;strong&gt; on the number of hashes a node may announce to a remote peer (apart from the 10MB &lt;code&gt;devp2p&lt;&#x2F;code&gt; network packet limit), but 4096 seems a sane chunk (128KB) to avoid a single packet hogging a network connection.&lt;&#x2F;li&gt;
&lt;li&gt;Nodes should only announce hashes of transactions that the remote peer could reasonably be considered not to know, but it is better to be over zealous than to have a nonce gap in the pool.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GetPooledTransactions (0x09): [hash_0: B_32, hash_1: B_32, ...]&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Specify one or more transactions to retrieve from a remote peer&#x27;s &lt;strong&gt;transaction pool&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;There is &lt;strong&gt;no protocol violating hard cap&lt;&#x2F;strong&gt; on the number of transactions a node may request from a remote peer (apart from the 10MB &lt;code&gt;devp2p&lt;&#x2F;code&gt; network packet limit), but the recipient may enforce an arbitrary cap on the reply (size or serving time), which &lt;strong&gt;must not&lt;&#x2F;strong&gt; be considered a protocol violation. To keep wasted bandwidth down (unanswered hashes), 256 seems like a sane upper limit.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;PooledTransactions (0x0a): [[nonce: P, receivingAddress: B_20, value: P, ...], ...]&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Specify transactions &lt;strong&gt;from the local transaction pool&lt;&#x2F;strong&gt; that the remote node requested via a &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt; message. The items in the list are transactions in the format described in the main Ethereum specification.&lt;&#x2F;li&gt;
&lt;li&gt;The transactions &lt;strong&gt;must&lt;&#x2F;strong&gt; be in same order as in the request, but it is &lt;strong&gt;ok&lt;&#x2F;strong&gt; to skip transactions that are not available. This way if the response size limit is reached, requesters will know which hashes to request again (everything from the last returned transaction) and which to assume unavailable (all gaps before the last returned transaction).&lt;&#x2F;li&gt;
&lt;li&gt;A peer may respond with an empty reply &lt;strong&gt;iff&lt;&#x2F;strong&gt; none of the hashes match transactions in its pool. It is allowed to announce a transaction that will not be served later if it gets included in a block in between.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Q: Why limit &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt; to retrieving items from the pool?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Apart from the transaction pool, transactions in Ethereum are always bundled together by the hundreds in block bodies and existing network retrievals honor this data layout. Allowing direct access to individual transactions in the database has no actionable use case, but would expose costly database reads into the network.&lt;&#x2F;p&gt;
&lt;p&gt;For transaction propagation purposes there is no reason to allow disk access, as any transaction finalized to disk will be broadcast inside a block anyway, so at worse there is a few hundred millisecond delay when a node gets the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Block propagation may be made a bit more optimal by transferring the contained transactions on demand only, but that is a whole EIP in itself, so better relax the protocol when all the requirements are known and not in advance. It would probably be enough to maintain a set of transactions included in recent blocks in memory.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Should &lt;code&gt;NewPooledTransactionHashes (0x08)&lt;&#x2F;code&gt; deduplicate from disk?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Similarly to &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt;, &lt;code&gt;NewPooledTransactionHashes (0x08)&lt;&#x2F;code&gt; should also only operate on the transaction pool and should ignore the disk altogether. During healthy network conditions, a transaction will propagate through much faster than it&#x27;s included in a block, so it will essentially be non-existent that a newly announced transaction is already on disk. By avoiding disk deduplication, we can avoid a DoS griefing by remote transaction announces.&lt;&#x2F;p&gt;
&lt;p&gt;If we want to be really correct and avoid even the slightest data race when deduplicating announcements, we can use the same recently-included-transactions trick that we discussed above to discard announcements that have recently become stale.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q: Why not reuse &lt;code&gt;Transaction (0x02)&lt;&#x2F;code&gt; instead of a new &lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt;?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Originally this EIP reused the existing &lt;code&gt;Transaction (0x02)&lt;&#x2F;code&gt; message as the reply to the &lt;code&gt;GetPooledTransactions (0x09)&lt;&#x2F;code&gt; request. This makes client code more complicated, because nodes constantly gossip &lt;code&gt;Transaction (0x02)&lt;&#x2F;code&gt; messages to each other as broadcasts, so it&#x27;s hard to match up which of the many messages is the actual reply to the request.&lt;&#x2F;p&gt;
&lt;p&gt;By keeping &lt;code&gt;Transaction (0x02)&lt;&#x2F;code&gt; and &lt;code&gt;PooledTransactions (0x0a)&lt;&#x2F;code&gt; as separate messages, we can also leave the protocol more flexible for future optimizations (e.g. adding request IDs, which are meaningless for gossip broadcasts).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP extends the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol in a backwards incompatible way and requires rolling out a new version, &lt;code&gt;eth&#x2F;65&lt;&#x2F;code&gt;. However, &lt;code&gt;devp2p&lt;&#x2F;code&gt; supports running multiple versions of the same wire protocol side-by-side, so rolling out &lt;code&gt;eth&#x2F;65&lt;&#x2F;code&gt; does not require client coordination, since non-updated clients can keep using &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change the consensus engine, thus does &lt;em&gt;not&lt;&#x2F;em&gt; require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Muir Glacier&quot;</title>
        <published>2019-11-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>James Hancock</name><uri>https://github.com/madeoftin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2387/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/hard-fork-to-address-the-ice-age-eip-2387" />
        

        <id>https://wg-eips.ritovision.com/2387/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2387"
            label="EIP-2387" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2387/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This meta-EIP specifies the changes included in the Ethereum hard fork named Muir Glacier. This hard fork addresses the impending Ice Age on Ethereum Mainnet and includes a commitment to solving the problems with the ice age more permanently.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum achieves a consistent block time due to its&#x27; difficulty retargeting algorithm. If a block-time is higher than 20 seconds, it reduces the difficulty, and if a block time is lower than 10 seconds, it increases the difficulty. This mechanism reaches typically an equilibrium of around 13-14 seconds. Included within this mechanism is something we refer to as the Difficulty Bomb or the Ice Age. It artificially adds to the difficulty in such a way that the retargeting mechanism, at some point, can not adapt to the increase, and we see increased block times throughout the network. The ice age increments every 100,000 blocks. It at first is barely noticeable, but once it is visible, there is a drastic effect on block-times in the network.&lt;&#x2F;p&gt;
&lt;p&gt;The primary problem with the Ice Age is that it is included in the complex mechanism that targets block times, which is an entirely separate in purpose. What is worse is due to being intwined with that algorithm, it is very difficult to simulate or predict its effect on the network. To predict the impact of the ice age, you must both make assumptions about the difficulty of main-net in the future, and predict the effect of changes in difficulty to the impact on the ice age and thus block-times.&lt;&#x2F;p&gt;
&lt;p&gt;This fork will push back the Iceage as far as far as is reasonable and will give us time to update the Iceage to no longer have these design problems. There are two solutions to consider within that time frame.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Update the mechanism so that behavior is predictable.&lt;&#x2F;li&gt;
&lt;li&gt;Remove the Iceage entirely&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Muir Glacier&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 9,200,000&lt;&#x2F;code&gt; on the Ethereum mainnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 7,117,117&lt;&#x2F;code&gt; on the Ropsten testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= N&#x2F;A&lt;&#x2F;code&gt; on the Kovan testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= N&#x2F;A&lt;&#x2F;code&gt; on the Rinkeby testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= N&#x2F;A&lt;&#x2F;code&gt; on the Görli testnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;included-eips&quot;&gt;Included EIPs&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2384&#x2F;&quot;&gt;EIP-2384&lt;&#x2F;a&gt;: Istanbul&#x2F;Berlin Difficulty Bomb Delay&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;I want to address the rationale for the intention of the Iceage and the implementation of the Iceage separately.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The original intentions of the ice age include:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;At the time of upgrades, inhibit unintentional growth of the resulting branching forks leading up to Eth 2.0. *&lt;&#x2F;li&gt;
&lt;li&gt;Encourage a prompt upgrade schedule for the path to Eth 2.0. *&lt;&#x2F;li&gt;
&lt;li&gt;Forces the community to come back into agreement repeatedly...and it gives whatever portion of the community that wants to a chance to fork off&lt;&#x2F;li&gt;
&lt;li&gt;Is a check for the Core Devs in the case that a decision is made to freeze the code base of clients without the blessing of the community.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;*Note: None of these effects the Freedom to Fork. They are meant to encourage core-devs and the community to upgrade along with the network and prevent the case where sleeper forks remain dormant only later to be resurrected. The requirement for an active fork is to change a client in a way to respond to the ice age. This is in fact what Ethereum Classic has done.&lt;&#x2F;p&gt;
&lt;p&gt;This is not meant to be exhaustive, but the ideas above capture much of what has been written on the original intentions and process of creating the fork. Any additions to this list that need to be made, I am happy to include. Regardless, to effectively implement an updated design for the ice age, all of the intentions need to be revisited and clarified as part of any updates. This clarification will give a clear expectation for the community and core developers moving forward.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The implementation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The existing implementation of the ice age, while it does work in practice, is unnecessarily complex to model and confusing to communicate to the community. Any updates to the design should be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Easy to model the effect on the network&lt;&#x2F;li&gt;
&lt;li&gt;Easy to predict when it occurs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This fork would give us time to address the community to understand their priorities better as far as the intentions of the Ice Age, and give time for proposals for better mechanisms to achieve those goals.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;poa-testnets&quot;&gt;POA Testnets&lt;&#x2F;h3&gt;
&lt;p&gt;Muir Glacier never activates on PoA chains – thus will have zero impact on &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;forkid&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;note-on-issuance-reduction&quot;&gt;Note on Issuance Reduction&lt;&#x2F;h3&gt;
&lt;p&gt;Previous Hardforks to address the Ice Age have also included reductions in the block reward from 5 Eth to 3 Eth to 2 Eth, respectively. In this case, there is no change in issuance, and the block reward remains 2 Eth per block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Muir Glacier Difficulty Bomb Delay</title>
        <published>2019-11-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Eric Conner</name><uri>https://github.com/econoar</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2384/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2384-difficulty-bomb-delay" />
        

        <id>https://wg-eips.ritovision.com/2384/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2384"
            label="EIP-2384" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2384/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The average block times are increasing due to the difficulty bomb (also known as the &quot;&lt;em&gt;ice age&lt;&#x2F;em&gt;&quot;) and slowly accelerating. This EIP proposes to delay the difficulty bomb for another 4,000,000 blocks (~611 days).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;MUIR_GLACIER_FORK_BLKNUM&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 9 million blocks later than the Homestead fork, which is also 7 million blocks later than the Byzantium fork and 4 million blocks later than the Constantinople fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The difficulty bomb started to become noticeable again on October 5th 2019 at block 8,600,000. Block times have been around 13.1s on average and now as of block 8,900,000 are around 14.3s. This will start to accelerate exponentially every 100,000 blocks. Estimating the added impact from the difficulty bomb on block times shows that we will see 20s block times near the end of December 2019 and 30s+ block times starting February 2020. This will start making the chain bloated and more costly to use. It&#x27;s best to delay the difficulty bomb again to around the time of expected launch of the Eth2 finality gadget.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fake_block_number = max(0, block.number - 9_000_000) if block.number &amp;gt;= MUIR_GLACIER_FORK_BLKNUM else block.number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This will delay the ice age by 52 million seconds (approximately 611 days), so the chain would be back at 20 second block times around July 2021. It&#x27;s important to note this pushes the ice age 4,000,000 blocks from ~block 8,800,000 NOT from when this EIP is activated in a fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation. Therefore, it should be included in a scheduled hardfork at a certain block number. It&#x27;s suggested to include this EIP shortly after the Istanbul fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation in it&#x27;s logic does not differ from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;649&#x2F;&quot;&gt;EIP-649&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1234&#x2F;&quot;&gt;EIP-1234&lt;&#x2F;a&gt;; an implementation for Parity-Ethereum is available in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity-ethereum&#x2F;pull&#x2F;9187&quot;&gt;parity-ethereum#9187&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;eth&#x2F;64: forkid-extended protocol handshake&quot;</title>
        <published>2019-11-08T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Péter Szilágyi</name><email>peterke@gmail.com</email>
	</author>
	
	<author>
		<name>Péter Szilágyi</name><uri>https://github.com/karalabe</uri>
	</author>
	
	<author>
		<name>Tim Beiko</name><uri>https://github.com/timbeiko</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2364/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2365" />
        

        <id>https://wg-eips.ritovision.com/2364/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2364"
            label="EIP-2364" />
        

        
        

        
        <summary type="html">Introduces validation of the `forkid` when handshaking with peers.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2364/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP specifies the inclusion of the &lt;code&gt;forkid&lt;&#x2F;code&gt;, originally defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;(EIP-2124)&lt;&#x2F;a&gt;, as a new field in the Ethereum wire protocol (&lt;code&gt;eth&lt;&#x2F;code&gt;) handshake. This change is implemented as a new version of the wire protocol, &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;&lt;code&gt;forkid&lt;&#x2F;code&gt; (EIP-2124)&lt;&#x2F;a&gt; was designed to permit two Ethereum nodes to quickly and cheaply decide if they are compatible or not, not only at a genesis&#x2F;networking level, but also from the perspective of the currently passed network updates (i.e. forks).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt; only defines how the &lt;code&gt;forkid&lt;&#x2F;code&gt; is calculated and validated, but does not specify how the &lt;code&gt;forkid&lt;&#x2F;code&gt; should be exchanged between peers. This EIP specifies the inclusion of the &lt;code&gt;forkid&lt;&#x2F;code&gt; as a new field in the Ethereum wire protocol (&lt;code&gt;eth&lt;&#x2F;code&gt;) handshake (releasing a new version, &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;By cross-validating &lt;code&gt;forkid&lt;&#x2F;code&gt; during the handshake, incompatible nodes can disconnect before expensive block exchanges and validations take place (PoW check, EVM execution, state reconstruction). This further prevents peer slots from being taken up by nodes that are incompatible, but have not yet been detected as such.&lt;&#x2F;p&gt;
&lt;p&gt;From a micro perspective, cutting off incompatible nodes from one another ensures that a node only spends its resources on tasks that are genuinely useful to it. The sooner we can decide the remote peer is useless, the less time and processing we expend in vain.&lt;&#x2F;p&gt;
&lt;p&gt;From a macro perspective, keeping incompatible nodes partitioned from one another ensures that disjoint clusters retain more resources for maintaining their own chain, thus raising the quality of service for all networks globally.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Implement &lt;code&gt;forkid&lt;&#x2F;code&gt; generation and validation per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Advertise a new &lt;code&gt;eth&lt;&#x2F;code&gt; protocol capability (version) at &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt;.
&lt;ul&gt;
&lt;li&gt;The old &lt;code&gt;eth&#x2F;63&lt;&#x2F;code&gt; protocol should still be kept alive side-by-side, until &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; is sufficiently adopted by implementors.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Redefine &lt;code&gt;Status (0x00)&lt;&#x2F;code&gt; for &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; to add a trailing &lt;code&gt;forkid&lt;&#x2F;code&gt; field:
&lt;ul&gt;
&lt;li&gt;Old packet: &lt;code&gt;[protocolVersion, networkId, td, bestHash, genesisHash]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;New packet: &lt;code&gt;[protocolVersion, networkId, td, bestHash, genesisHash, forkid]&lt;&#x2F;code&gt;,
where &lt;code&gt;forkid&lt;&#x2F;code&gt; is &lt;code&gt;[forkHash: [4]byte, forkNext: uint64]&lt;&#x2F;code&gt; (fields per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt; ).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Whenever two peers connect using the &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; protocol, the updated &lt;code&gt;Status&lt;&#x2F;code&gt; message must be sent as the protocol handshake, and each peer must validate the remote &lt;code&gt;forkid&lt;&#x2F;code&gt;, disconnecting at a detected incompatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The specification is tiny since most parts are already specified in EIP-2124. &lt;code&gt;eth&#x2F;63&lt;&#x2F;code&gt; is not specified as an EIP, but is maintained in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&quot;&gt;ethereum&#x2F;devp2p&lt;&#x2F;a&gt; Github repository.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eip-2124-mentions-advertising-the-forkid-in-the-discovery-protocol-too-how-does-that-compare-to-advertising-in-the-eth-protocol-why-is-the-redundancy-needed&quot;&gt;EIP-2124 mentions advertising the &lt;code&gt;forkid&lt;&#x2F;code&gt; in the discovery protocol too. How does that compare to advertising in the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol? Why is the redundancy needed?&lt;&#x2F;h3&gt;
&lt;p&gt;Advertising and validating the &lt;code&gt;forkid&lt;&#x2F;code&gt; in the discovery protocol is a more optimal solution, as it can help avoid the cost of setting up the TCP connection and cryptographic RLPx stream, only to be torn down if &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; rejects it.&lt;&#x2F;p&gt;
&lt;p&gt;Compared to the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol however, discovery is a bit fuzzy. The goal there is to suggest potential peers, not to be fool-proof. Information may be outdated, nodes may have changed or disappeared. Discovery can do a rough filtering, but more precision is still needed afterwards.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, &lt;code&gt;forkid&lt;&#x2F;code&gt; validation via the discovery protocol requires ENR implementation (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;778&#x2F;&quot;&gt;EIP-778&lt;&#x2F;a&gt;) and ENR extension support (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;868&#x2F;&quot;&gt;EIP-868&lt;&#x2F;a&gt;), which is not mandated by the Ethereum network currently. Lastly, the discovery protocol is just one way to find peers, but systems that cannot use UDP or that rely on other mechanism (e.g. DNS discovery)) still need a way to filter connections.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-forkid-implicitly-contains-the-genesis-hash-checksummed-into-the-fork-hash-field-why-doesn-t-this-proposal-remove-the-genesishash-field-from-the-eth-handshake&quot;&gt;The &lt;code&gt;forkid&lt;&#x2F;code&gt; implicitly contains the genesis hash checksummed into the &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; field. Why doesn&#x27;t this proposal remove the &lt;code&gt;genesisHash&lt;&#x2F;code&gt; field from the &lt;code&gt;eth&lt;&#x2F;code&gt; handshake?&lt;&#x2F;h3&gt;
&lt;p&gt;Originally this EIP did remove it as redundant data, since filtering based on the &lt;code&gt;forkid&lt;&#x2F;code&gt; is a superset of filtering based on genesis hash. The reason for backing out of that decision was that the genesis hash may be useful for other things too, not just connection filtering (network crawlers use it currently to split nodes across networks).&lt;&#x2F;p&gt;
&lt;p&gt;Although the &lt;code&gt;forkid&lt;&#x2F;code&gt; will hopefully take over all the roles of the genesis hash currently in use, there&#x27;s no reason to be overly aggressive in deduplicating data. It&#x27;s fine to keep both side-by-side for now, and remove in a future version when 3rd party infrastructures switch over.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP extends the &lt;code&gt;eth&lt;&#x2F;code&gt; protocol handshake in a backwards incompatible way and requires rolling out a new version, &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt;. However, &lt;code&gt;devp2p&lt;&#x2F;code&gt; supports running multiple versions of the same wire protocol side-by-side, so rolling out &lt;code&gt;eth&#x2F;64&lt;&#x2F;code&gt; does not require client coordination, since non-updated clients can keep using &lt;code&gt;eth&#x2F;63&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not change the consensus engine, thus does &lt;em&gt;not&lt;&#x2F;em&gt; require a hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;For calculating and validating fork IDs, see test cases in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2124&#x2F;&quot;&gt;EIP-2124&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ERC-721 Consecutive Transfer Extension</title>
        <published>2019-10-08T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Sean Papanikolas</name><uri>https://github.com/pizzarob</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2309/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2309" />
        

        <id>https://wg-eips.ritovision.com/2309/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2309"
            label="ERC-2309" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2309/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standardized event emitted when creating&#x2F;transferring one, or many non-fungible tokens using consecutive token identifiers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The optional ERC-721 Consecutive Transfer Extension provides a standardized event which could be emitted during the creation&#x2F;transfer of one, or many non-fungible tokens. This standard does not set the expectation of how you might create&#x2F;transfer many tokens it is only concerned with the event emitted after the creation, or transfer of ownership of these tokens. This extension assumes that token identifiers are in consecutive order.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This extension provides even more scalibility of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721 specification&lt;&#x2F;a&gt;. It is possible to create, transfer, and burn 2^256 non-fungible tokens in one transaction. However, it is not possible to emit that many &lt;code&gt;Transfer&lt;&#x2F;code&gt; events in one transaction. The &lt;code&gt;Transfer&lt;&#x2F;code&gt; event is part of the original specification which states:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This emits when ownership of any NFT changes by any mechanism.
This event emits when NFTs are created (&lt;code&gt;from&lt;&#x2F;code&gt; == 0) and destroyed
(&lt;code&gt;to&lt;&#x2F;code&gt; == 0). Exception: during contract creation, any number of NFTs
may be created and assigned without emitting Transfer. At the time of
any transfer, the approved address for that NFT (if any) is reset to none.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This allows for the original &lt;code&gt;Transfer&lt;&#x2F;code&gt; event to be emitted for one token at a time, which in turn gives us O(n) time complexity. Minting one billion NFTs can be done in one transaction using efficient data structures, but in order to emit the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event - according to the original spec - one would need a loop with one billion iterations which is bound to run out of gas, or exceed transaction timeout limits. This cannot be accomplished with the current spec. This extension solves that problem.&lt;&#x2F;p&gt;
&lt;p&gt;Many decentralized marketplaces and block explorers utilize the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event as a way to determine which NFTs an address owns. The Consecutive Transfer Extension provides a standard mechanism for these platforms to use to determine ownership of many tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL
NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and
&quot;OPTIONAL&quot; in this document are to be interpreted as described in
RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;ERC-721 compliant contracts MAY implement this Consecutive Transfer Extension to provide a standard event to be emitted at the time of creation, burn, or transfer of one or many consecutive tokens&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The address executing the transaction &lt;strong&gt;MUST&lt;&#x2F;strong&gt; own all the tokens within the range of &lt;code&gt;fromTokenId&lt;&#x2F;code&gt; and &lt;code&gt;toTokenId&lt;&#x2F;code&gt;, or &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be an approved operator to act on the owners behalf.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;fromTokenId&lt;&#x2F;code&gt; and &lt;code&gt;toTokenId&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be a consecutive range of tokens IDs.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;fromTokenId&lt;&#x2F;code&gt;, &lt;code&gt;fromAddress&lt;&#x2F;code&gt;, and &lt;code&gt;toAddress&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be indexed parameters&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;toTokenId&lt;&#x2F;code&gt; &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be an indexed parameter&lt;&#x2F;p&gt;
&lt;p&gt;When minting&#x2F;creating tokens, the &lt;code&gt;fromAddress&lt;&#x2F;code&gt; argument &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address).&lt;&#x2F;p&gt;
&lt;p&gt;When burning&#x2F;destroying tokens, the &lt;code&gt;toAddress&lt;&#x2F;code&gt; argument &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address).&lt;&#x2F;p&gt;
&lt;p&gt;When emitting the ConsecutiveTransfer event the Transfer event &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be emitted&lt;&#x2F;p&gt;
&lt;p&gt;Contracts that implement the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event &lt;strong&gt;MAY&lt;&#x2F;strong&gt; still use the original &lt;code&gt;Transfer&lt;&#x2F;code&gt; event, however when emitting the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; be emitted.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ConsecutiveTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toTokenId&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fromAddress&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toAddress&lt;&#x2F;span&gt;&lt;span&gt;)&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;examples&quot;&gt;Examples&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event can be used for a single token as well as many tokens:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Single token creation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;emit ConsecutiveTransfer(1, 1, address(0), toAddress);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Batch token creation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;emit ConsecutiveTransfer(1, 100000, address(0), toAddress);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Batch token transfer&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;emit ConsecutiveTransfer(1, 100000, fromAddress, toAddress);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Burn&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;emit ConsecutiveTransfer(1, 100000, from, address(0));&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Standardizing the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event gives decentralized platforms a standard way of determining ownership of large quantities of non-fungible tokens without the need to support a new token standard. There are many ways in which the batch creation and transfer of NFTs can be implemented. The Consecutive Transfer Extension allows contract creators to implement batch creation, transfer, and burn methods however they see fit, but provides a standardized event in which all implementations can use. By specifying a range of consecutive token identifiers we can easily cover the transfer, or creation of 2^(256) tokens and decentralized platforms can react accordingly.&lt;&#x2F;p&gt;
&lt;p&gt;Take this example. I sell magical fruit and have a farm with 10,000 magical fruit trees each with different fruit and 1,000 new trees every few years. I want to turn each tree into a non-fungible token that people can own. Each person that owns one of my non-fungible tree tokens will receive a quarterly percentage of each harvest from that tree. The problem is that I would need to create and transfer each of these tokens individually - which will cost me a lot of time and money and frankly would keep me from doing this.&lt;&#x2F;p&gt;
&lt;p&gt;With this extension I would be able to mint my initial 10,000  tree tokens in one transaction. I would be able to quickly and cheaply mint my additional 1,000  tree tokens when a new batch is planted. I would then be able to transfer all of the 10,000+ tree tokens to a special smart contract that keeps track of the selling and distribution of funds in one transaction all while adhering to a specified standard.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Rationale to have a single event that covers minting, burning, and transferring&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event can be used to cover minting, burning, and transferring events. While there may have been confusion in the beginning adhering to transfer to&#x2F;from &quot;0&quot; pattern this is mitigated by checking for the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; topic and verifying the emitting contract supports the ERC-721 interface by using the ERC-165 standard.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Indexed event parameters&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Events in Solidity can have up to three indexed parameters which will make it possible to filter for specific values of indexed arguments. This standard sets the &lt;code&gt;fromAddress&lt;&#x2F;code&gt;, &lt;code&gt;toAddress&lt;&#x2F;code&gt;, and &lt;code&gt;fromTokenId&lt;&#x2F;code&gt; as the indexed parameters. The &lt;code&gt;toTokenId&lt;&#x2F;code&gt; can be retrieved from the data part of the log. The reason for this is that more often than not one may be searching for events to learn about the history of ownership for a given address. The &lt;code&gt;fromTokenId&lt;&#x2F;code&gt; can then be retrieved along with the other two indexed parameters for simplicity. Then one only needs to decode the log data which is ensured to be the &lt;code&gt;toTokenId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Rationale to not emit &lt;code&gt;Transfer&lt;&#x2F;code&gt; when &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; is also emitted&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can lead to bugs and unnecessary complex logic for platforms using these events to track token ownership. When transferring a single token it is acceptable to emit the original &lt;code&gt;Transfer&lt;&#x2F;code&gt; event, but the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event should not be emitted during the same transaction and vice-versa.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Comparing 2309 and 1155&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As the NFT market continues to grow so does the need for the ability to scale the smart contracts. Users need to be able to do things like mint a massive amount of tokens at one time, transfer a massive amount of tokens, and be able to track ownership of all these assets. We need to do this in a way that is cost effective and doesn’t fail under the confines of the Ethereum blockchain. As millions of tokens are minted we need contracts with the ability to scale.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; was created and added as a standard in 2019 to try to solve these problems, but it falls short when it comes to minting massive amounts of unique tokens in a cost-effective way. With ERC-1155 it’s either going to cost hundreds (or thousands) of dollars or it’s going to run out of gas. ERC-1155 works well when minting many semi-fungible tokens but falls short when minting many unique tokens. Using the 2309 standard you could mint millions of blank NFTs upfront and update the metadata for each one in a cost effective way.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This extension was written to allow for the smallest change possible to the original ERC-721 spec while still providing a mechanism to track the creation, transfer, and deletion of a massive amount of tokens. While it is a minimal change the effects on platforms that only use the original &lt;code&gt;Transfer&lt;&#x2F;code&gt; event to index token ownership would be severe. They would not be properly recording token ownership information that could be known by listening for the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event. For platforms that wish to support the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event it would be best to support both the original &lt;code&gt;Transfer&lt;&#x2F;code&gt; event and the &lt;code&gt;ConsecutiveTransfer&lt;&#x2F;code&gt; event to track token ownership.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no security considerations related directly to the implementation of this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Wallet Permissions System</title>
        <published>2019-08-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Dan Finlay</name><uri>https://github.com/danfinlay</uri>
	</author>
	
	<author>
		<name>Erik Marks</name><uri>https://github.com/rekmarks</uri>
	</author>
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2255/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/web3-login-permissions/3583" />
        

        <id>https://wg-eips.ritovision.com/2255/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2255"
            label="EIP-2255" />
        

        
        

        
        <summary type="html">An interface to restrict access to sensitive methods</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2255/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP adds two new wallet-namespaced RPC endpoints, &lt;code&gt;wallet_getPermissions&lt;&#x2F;code&gt; and &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt;, providing a standard interface for requesting and checking permissions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Wallets are responsible for mediating interactions between untrusted applications and users&#x27; keys through appropriate user consent. Today, wallets always prompt the user for every action. This provides security at the cost of substantial user friction. We believe that a single permissions request can achieve the same level of security with vastly improved UX.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern of permissions requests (typically using Oauth2) is common around the web, making it a very familiar pattern:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2255&#x2F;.&#x2F;assets&#x2F;facebook_permissions.png&quot; alt=&quot;Facebook Permissions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2255&#x2F;.&#x2F;assets&#x2F;log_in_with_apple.jpeg&quot; alt=&quot;Log in With Apple&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Many web3 applications today begin their sessions with a series of repetitive requests:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reveal your wallet address to this site.&lt;&#x2F;li&gt;
&lt;li&gt;Switch to a preferred network.&lt;&#x2F;li&gt;
&lt;li&gt;Sign a cryptographic challenge.&lt;&#x2F;li&gt;
&lt;li&gt;Grant a token allowance to our contract.&lt;&#x2F;li&gt;
&lt;li&gt;Send a transaction to our contract.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Many of these (and possibly all), and many more (like decryption), could be generalized into a set of human-readable permissions prompts on the original sign-in screen, and additional permissions could be requested only as needed:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2255&#x2F;.&#x2F;assets&#x2F;permissions.png&quot; alt=&quot;Sample prompt screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each of these permissions could be individually rejected, or even &lt;em&gt;attenuated&lt;&#x2F;em&gt;--adjusted to meet the user&#x27;s terms (for example, a sign-in request could have a user-added expiration date, and a token allowance could be adjusted by the user when it is requested).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal adds two new methods to a wallet&#x27;s web3 provider API: &lt;code&gt;wallet_getPermissions&lt;&#x2F;code&gt; and &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-getpermissions&quot;&gt;&lt;code&gt;wallet_getPermissions&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;wallet_getPermissions&lt;&#x2F;code&gt; method is used for getting an array of current permissions (empty by default). It takes no parameters and returns an array of &lt;code&gt;Permission&lt;&#x2F;code&gt; objects.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-getpermissions-returns&quot;&gt;&lt;code&gt;wallet_getPermissions&lt;&#x2F;code&gt; Returns&lt;&#x2F;h4&gt;
&lt;p&gt;The format of the returned permissions MUST be an array of &lt;code&gt;Permission&lt;&#x2F;code&gt; objects, which are defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Caveat&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Permission&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  invoker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  parentCapability&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  caveats&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Caveat&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;invoker&lt;&#x2F;code&gt; is a URI used to identify the source of the current dapp (e.g. &lt;code&gt;https:&#x2F;&#x2F;your-site.com&#x2F;&lt;&#x2F;code&gt;). The term &lt;code&gt;parentCapability&lt;&#x2F;code&gt; refers to the method that is being permitted (e.g. &lt;code&gt;eth_accounts&lt;&#x2F;code&gt;). The &lt;code&gt;caveats&lt;&#x2F;code&gt; array represents the specific restrictions applied to the permitted method. The &lt;code&gt;type&lt;&#x2F;code&gt; of a &lt;code&gt;Caveat&lt;&#x2F;code&gt; is a string, and the &lt;code&gt;value&lt;&#x2F;code&gt; is an arbitrary JSON value. The &lt;code&gt;value&lt;&#x2F;code&gt; of a &lt;code&gt;Caveat&lt;&#x2F;code&gt; is only meaningful in the context of the &lt;code&gt;type&lt;&#x2F;code&gt; of the &lt;code&gt;Caveat&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-requestpermissions&quot;&gt;&lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; method is used for an application to request additional permissions. It MUST take a single parameter, a &lt;code&gt;PermissionRequest&lt;&#x2F;code&gt; object, and MUST return an array of &lt;code&gt;RequestedPermission&lt;&#x2F;code&gt; objects.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-requestpermissions-parameters&quot;&gt;&lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; Parameters&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; method takes a single parameter, a &lt;code&gt;PermissionRequest&lt;&#x2F;code&gt; object, which is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PermissionRequest&lt;&#x2F;span&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;span class=&quot;z-variable&quot;&gt;methodName&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;caveatName&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&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;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 &lt;code&gt;methodName&lt;&#x2F;code&gt; is the name of the method for which the permission is being requested (e.g. &lt;code&gt;eth_accounts&lt;&#x2F;code&gt;). The &lt;code&gt;caveatName&lt;&#x2F;code&gt; is the name of the caveat being applied to the permission (e.g. &lt;code&gt;requiredMethods&lt;&#x2F;code&gt;). The caveat value is the value of the caveat (e.g. &lt;code&gt;[&quot;signTypedData_v3&quot;]&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Attempted requests to a restricted method must fail with an error, until a &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; request is made and accepted by the user.&lt;&#x2F;p&gt;
&lt;p&gt;If a &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; request is rejected, it should throw an error with a &lt;code&gt;code&lt;&#x2F;code&gt; value equal to &lt;code&gt;4001&lt;&#x2F;code&gt; as per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;&quot;&gt;EIP-1193&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;wallet-requestpermissions-returns&quot;&gt;&lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; Returns&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; method returns an array of &lt;code&gt;RequestedPermission&lt;&#x2F;code&gt; objects, which are defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RequestedPermission&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  parentCapability&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  date&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&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 &lt;code&gt;parentCapability&lt;&#x2F;code&gt; is the name of the method for which the permission is being requested (e.g. &lt;code&gt;eth_accounts&lt;&#x2F;code&gt;). The &lt;code&gt;date&lt;&#x2F;code&gt; is the timestamp of the request, in Unix time, and is optional.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;While the current model of getting user consent on a per-action basis has high security, there are huge usability gains to be had bo getting more general user consent which can cover broad categories of usage, which can be expressed in a more human-readable way. This pattern has a variety of benefits to offer different functions within a web3 wallet.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;requestPermissions&lt;&#x2F;code&gt; method can be expanded to include other options related to the requested permissions, for example, sites could request accounts with specific abilities. For example, a website like an exchange that requires &lt;code&gt;signTypedData_v3&lt;&#x2F;code&gt; (which is not supported by some hardware wallets), might want to specify that requirement. This would allow wallets to display only compatible accounts, while preserving the user&#x27;s privacy and choice regarding how they are storing their keys.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;requesting-permissions&quot;&gt;Requesting permissions&lt;&#x2F;h3&gt;
&lt;p&gt;The following example should prompt the user to approve the &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; permission, and return the permission object if approved.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&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&gt;  method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;requestPermissions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;  params&lt;&#x2F;span&gt;&lt;span&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;        requiredMethods&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;signTypedData_v3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&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;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;span&gt;)&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;getting-permissions&quot;&gt;Getting permissions&lt;&#x2F;h3&gt;
&lt;p&gt;The following example should return the current permissions object.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&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&gt;  method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;getPermissions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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&gt;)&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;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;server-side-request-forgery-ssrf&quot;&gt;Server-Side Request Forgery (SSRF)&lt;&#x2F;h3&gt;
&lt;p&gt;This consideration is applicable if the favicon of a website is to be displayed.&lt;&#x2F;p&gt;
&lt;p&gt;Wallets should be careful about making arbitrary requests to URLs. As such, it is recommended for wallets to sanitize the URI by whitelisting specific schemes and ports. A vulnerable wallet could be tricked into, for example, modifying data on a locally-hosted redis database.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Canonicalize the name of network ID 1 and chain ID 1</title>
        <published>2019-08-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>William Entriken</name><uri>https://github.com/fulldecent</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2228/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2228" />
        

        <id>https://wg-eips.ritovision.com/2228/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="informational"
                label="Informational" />
            
        

        
        <category
            term="tag:eip:2228"
            label="EIP-2228" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2228/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The Ethereum network with network ID 1 and chain ID 1 is named Ethereum Mainnet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The name for the Ethereum network with network ID 1 and chain ID 1 shall be Ethereum Mainnet or just Mainnet. This is a proper noun.&lt;&#x2F;p&gt;
&lt;p&gt;This standard specifies the name for this network and provides reference examples in an effort to standardize the word choice and provide a common language for use to refer to this network.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The Ethereum network with network ID 1 and chain ID 1 is referenced using several conflicting names across EIPs, client implementations, and information published on the internet at large. In several locations, even documents written by the same author use inconsistent names to refer to the Ethereum network with network ID 1 and chain ID 1. Names in use at the time of this writing include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;main net&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;mainnet&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Main net&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Mainnet&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The network name for network ID 1 and chain ID 1 shall be Ethereum Mainnet, or just Mainnet if the context is known to be discussing Ethereum networks. This IS a proper noun. Several examples are given below which differentiate between usage of the name of the network versus a descriptive reference to the network.&lt;&#x2F;p&gt;
&lt;p&gt;Any name or word styling (i.e. capitalization of the letters) of the network which is inconsistent with the test cases cited below shall NOT be used.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trademark-note&quot;&gt;Trademark note&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;Ethereum&quot; is trademarked by the Ethereum Foundation. For more information on your obligations when mentioning &quot;Ethereum&quot;, and possibly &quot;Ethereum Mainnet&quot;, see:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;USPTO registration number 5110579 by Ethereum Foundation&lt;&#x2F;li&gt;
&lt;li&gt;The note &quot;you must not use [this mark] without the prior written permission of the Foundation&quot; on the Ethereum Foundation website, Terms of Use page&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Choosing common word use promotes interoperability of implementations and increases customer awareness. Also, it adds a sense of professionalism when customers see the same word and word styling (i.e. capitalization of letters) across different implementations.&lt;&#x2F;p&gt;
&lt;p&gt;Anybody that has travelled to certain countries and seen an &quot;IPhone [sic]&quot; repair store should immediately recognize that this is off-brand and unofficial. Likewise, the astute customer of Ethereum should recognize if they see the network referred to using inconsistent names in different software, so let&#x27;s avoid this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MetaMask previously used &quot;Main Ethereum Network&quot; in the account network chooser. MetaMask has been updated consistent with this EIP.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;References to Mainnet that are inconsistent with this specification are made in: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2&#x2F;&quot;&gt;EIP-2&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;779&#x2F;&quot;&gt;EIP-779&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;190&#x2F;&quot;&gt;EIP-190&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;225&#x2F;&quot;&gt;EIP-225&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1013&#x2F;&quot;&gt;EIP-1013&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2028&#x2F;&quot;&gt;EIP-2028&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2387&#x2F;&quot;&gt;EIP-2387&lt;&#x2F;a&gt;. For consistency, we recommend the editor will update EIPs to consistently use the name as specified in this EIP.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;examples-referencing-the-name-of-the-network-white-check-mark&quot;&gt;Examples referencing the name of the network ✅&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The contract was deployed to Ethereum Mainnet.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Ethereum runs many applications, this Dapp was deployed to Mainnet.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;No specification is made on whether Dapp, dapp, dApp, etc. is preferred.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;SWITCH TO MAINNET&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This example shows a user interface which is in uppercase. To be semantically correct, this could be written in HTML as &lt;code&gt;&amp;lt;span style=&quot;text-transform: uppercase&quot;&amp;gt;Switch to Mainnet&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;switch to mainnet&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This example shows a user interface which is in lowercase. To be semantically correct, this could be written in HTML as &lt;code&gt;&amp;lt;span style=&quot;text-transform: lowercase&quot;&amp;gt;Switch to Mainnet&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;examples-referencing-the-network-in-a-descriptive-way-white-check-mark&quot;&gt;Examples referencing the network in a descriptive way ✅&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Mainnet has ### times the number of transactions as the test networks.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;examples-of-other-correct-word-usage-white-check-mark&quot;&gt;Examples of other correct word usage ✅&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The main network on Ethereum is Mainnet&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This shows that &quot;main&quot; is used as a descriptive word, but Mainnet is the specific network which is having network ID 1 and chain ID 1.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;examples-of-poor-word-choice-avoid-this-x&quot;&gt;Examples of poor word choice (avoid this) ❌&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Deploy your contract to the Ethereum main network.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is referring to a &quot;main&quot; network which is context-dependent. If you were reading this text on a page about Ethereum Classic, they would be referring to network ID 2 and chain ID 62. Therefore this word usage is less crisp. Do NOT use wording like this.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Connect to mainnet.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;These words literally mean nothing. The lowercase, not-proper-noun word &quot;mainnet&quot; is not a plain English word and it should not be in any dictionary. Do NOT use wording like this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Structured Definitions for Net Gas Metering</title>
        <published>2019-07-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Wei Tang</name><uri>https://github.com/sorpaas</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2200/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/sorpaas/EIPs/issues/1" />
        

        <id>https://wg-eips.ritovision.com/2200/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2200"
            label="EIP-2200" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2200/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This is an EIP that implements net gas metering. It&#x27;s a combined
version of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;&quot;&gt;EIP-1283&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1706&#x2F;&quot;&gt;EIP-1706&lt;&#x2F;a&gt;, with a structured definition so as
to make it interoperable with other gas changes such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;&quot;&gt;EIP-1884&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP provides a structured definition of net gas metering changes
for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; opcode, enabling new usages for contract storage, and
reducing excessive gas costs where it doesn’t match how most
implementation works.&lt;&#x2F;p&gt;
&lt;p&gt;This is a combination of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;&quot;&gt;EIP-1283&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1706&#x2F;&quot;&gt;EIP-1706&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a way for gas metering on &lt;code&gt;SSTORE&lt;&#x2F;code&gt;, using information
that is more universally available to most implementations, and
require as little change in implementation structures as possible.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Storage slot’s original value.&lt;&#x2F;li&gt;
&lt;li&gt;Storage slot’s current value.&lt;&#x2F;li&gt;
&lt;li&gt;Refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Usages that benefits from this EIP’s gas reduction scheme includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Subsequent storage write operations within the same call frame. This
includes reentry locks, same-contract multi-send, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Exchange storage information between sub call frame and parent call
frame, where this information does not need to be persistent outside
of a transaction. This includes sub-frame error codes and message
passing, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The original definition of EIP-1283 created a danger of a new kind of
reentrancy attacks on existing contracts as Solidity by default grants
a &quot;stipend&quot; of 2300 gas to simple transfer calls. This danger is
easily mitigated if &lt;code&gt;SSTORE&lt;&#x2F;code&gt; is not allowed in low gasleft state,
without breaking the backward compatibility and the original intention
of EIP-1283.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP also replaces the original EIP-1283 value definitions of gas
by parameters, so that it&#x27;s more structured, and easier to define
changes in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Define variables &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt;, &lt;code&gt;SSTORE_SET_GAS&lt;&#x2F;code&gt;, &lt;code&gt;SSTORE_RESET_GAS&lt;&#x2F;code&gt; and
&lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt;. The old and new values for those variables
are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt;: changed from &lt;code&gt;200&lt;&#x2F;code&gt; to &lt;code&gt;800&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SSTORE_SET_GAS&lt;&#x2F;code&gt;: &lt;code&gt;20000&lt;&#x2F;code&gt;, not changed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SSTORE_RESET_GAS&lt;&#x2F;code&gt;: &lt;code&gt;5000&lt;&#x2F;code&gt;, not changed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt;: &lt;code&gt;15000&lt;&#x2F;code&gt;, not changed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Change the definition of EIP-1283 using those variables. The new
specification, combining EIP-1283 and EIP-1706, will look like
below. The terms &lt;em&gt;original value&lt;&#x2F;em&gt;, &lt;em&gt;current value&lt;&#x2F;em&gt; and &lt;em&gt;new value&lt;&#x2F;em&gt; are
defined in EIP-1283.&lt;&#x2F;p&gt;
&lt;p&gt;Replace &lt;code&gt;SSTORE&lt;&#x2F;code&gt; opcode gas cost calculation (including refunds) with
the following logic:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;gasleft&lt;&#x2F;em&gt; is less than or equal to gas stipend, fail the current
call frame with &#x27;out of gas&#x27; exception.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; equals &lt;em&gt;new value&lt;&#x2F;em&gt; (this is a no-op), &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt;
is deducted.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; does not equal &lt;em&gt;new value&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; equals &lt;em&gt;current value&lt;&#x2F;em&gt; (this storage slot has
not been changed by the current execution context)
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, &lt;code&gt;SSTORE_SET_GAS&lt;&#x2F;code&gt; is deducted.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, &lt;code&gt;SSTORE_RESET_GAS&lt;&#x2F;code&gt; gas is deducted. If &lt;em&gt;new value&lt;&#x2F;em&gt; is
0, add &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; gas to refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; does not equal &lt;em&gt;current value&lt;&#x2F;em&gt; (this storage
slot is dirty), &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt; gas is deducted. Apply both of the
following clauses.
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is not 0
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; is 0 (also means that &lt;em&gt;new value&lt;&#x2F;em&gt; is not
0), remove &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; gas from refund
counter.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;new value&lt;&#x2F;em&gt; is 0 (also means that &lt;em&gt;current value&lt;&#x2F;em&gt; is not
0), add &lt;code&gt;SSTORE_CLEARS_SCHEDULE&lt;&#x2F;code&gt; gas to refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; equals &lt;em&gt;new value&lt;&#x2F;em&gt; (this storage slot is
reset)
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, add &lt;code&gt;SSTORE_SET_GAS - SLOAD_GAS&lt;&#x2F;code&gt; to
refund counter.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, add &lt;code&gt;SSTORE_RESET_GAS - SLOAD_GAS&lt;&#x2F;code&gt; gas to refund
counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;An implementation should also note that with the above definition, if
the implementation uses call-frame refund counter, the counter can go
negative. If the implementation uses transaction-wise refund counter,
the counter always stays positive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP mostly achieves what a transient storage tries to do
(&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1087&#x2F;&quot;&gt;EIP-1087&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1153&#x2F;&quot;&gt;EIP-1153&lt;&#x2F;a&gt;), but without the complexity of introducing the
concept of &quot;dirty maps&quot;, or an extra storage struct.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We don&#x27;t suffer from the optimization limitation of
EIP-1087. EIP-1087 requires keeping a dirty map for storage changes,
and implicitly makes the assumption that a transaction&#x27;s storage
changes are committed to the storage trie at the end of a
transaction. This works well for some implementations, but not for
others. After &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;658&#x2F;&quot;&gt;EIP-658&lt;&#x2F;a&gt;, an efficient storage cache implementation
would probably use an in-memory trie (without RLP encoding&#x2F;decoding)
or other immutable data structures to keep track of storage changes,
and only commit changes at the end of a block. For them, it is
possible to know a storage&#x27;s original value and current value, but
it is not possible to iterate over all storage changes without
incurring additional memory or processing costs.&lt;&#x2F;li&gt;
&lt;li&gt;It never costs more gas compared with the current scheme.&lt;&#x2F;li&gt;
&lt;li&gt;It covers all usages for a transient storage. Clients that are easy
to implement EIP-1087 will also be easy to implement this
specification. Some other clients might require a little bit extra
refactoring on this. Nonetheless, no extra memory or processing cost
is needed on runtime.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Regarding &lt;code&gt;SSTORE&lt;&#x2F;code&gt; gas cost and refunds, see Appendix for proofs of
properties that this EIP satisfies.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For &lt;em&gt;absolute gas used&lt;&#x2F;em&gt; (that is, actual &lt;em&gt;gas used&lt;&#x2F;em&gt; minus &lt;em&gt;refund&lt;&#x2F;em&gt;),
this EIP is equivalent to EIP-1087 for all cases.&lt;&#x2F;li&gt;
&lt;li&gt;For one particular case, where a storage slot is changed, reset to
its original value, and then changed again, EIP-1283 would move more
gases to refund counter compared with EIP-1087.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Examine examples provided in EIP-1087&#x27;s Motivation (with &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt; being
&lt;code&gt;200&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If a contract with empty storage sets slot 0 to 1, then back to 0,
it will be charged &lt;code&gt;20000 + 200 - 19800 = 400&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;A contract with empty storage that increments slot 0 5 times will be
charged &lt;code&gt;20000 + 5 * 200 = 21000&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;A balance transfer from account A to account B followed by a
transfer from B to C, with all accounts having nonzero starting and
ending balances, it will cost &lt;code&gt;5000 * 3 + 200 - 4800 = 10400&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In order to keep in place the implicit reentrancy protection of
existing contracts, transactions should not be allowed to modify state
if the remaining gas is lower than the gas stipend given to
&quot;transfer&quot;&#x2F;&quot;send&quot; in Solidity. These are other proposed remediations
and objections to implementing them:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Drop EIP-1283 and abstain from modifying &lt;code&gt;SSTORE&lt;&#x2F;code&gt; cost
&lt;ul&gt;
&lt;li&gt;EIP-1283 is an important update&lt;&#x2F;li&gt;
&lt;li&gt;It was accepted and implemented on test networks and in clients.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Add a new call context that permits LOG opcodes but not changes to state.
&lt;ul&gt;
&lt;li&gt;Adds another call type beyond existing regular&#x2F;staticcall&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Raise the cost of &lt;code&gt;SSTORE&lt;&#x2F;code&gt; to dirty slots to &amp;gt;=2300 gas
&lt;ul&gt;
&lt;li&gt;Makes net gas metering much less useful.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Reduce the gas stipend
&lt;ul&gt;
&lt;li&gt;Makes the stipend almost useless.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Increase the cost of writes to dirty slots back to 5000 gas, but add
4800 gas to the refund counter
&lt;ul&gt;
&lt;li&gt;Still doesn’t make the invariant explicit.&lt;&#x2F;li&gt;
&lt;li&gt;Requires callers to supply more gas, just to have it refunded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Add contract metadata specifying per-contract EVM version, and only
apply &lt;code&gt;SSTORE&lt;&#x2F;code&gt; changes to contracts deployed with the new version.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP requires a hard fork to implement. No gas cost increase is
anticipated, and many contracts will see gas reduction.&lt;&#x2F;p&gt;
&lt;p&gt;Performing &lt;code&gt;SSTORE&lt;&#x2F;code&gt; has never been possible with less than 5000 gas, so
it does not introduce incompatibility to the Ethereum Mainnet. Gas
estimation should account for this requirement.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Used Gas&lt;&#x2F;th&gt;&lt;th&gt;Refund&lt;&#x2F;th&gt;&lt;th&gt;Original&lt;&#x2F;th&gt;&lt;th&gt;1st&lt;&#x2F;th&gt;&lt;th&gt;2nd&lt;&#x2F;th&gt;&lt;th&gt;3rd&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1612&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20812&lt;&#x2F;td&gt;&lt;td&gt;19200&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;4200&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556003600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;4200&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5812&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1612&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600160005560006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;40818&lt;&#x2F;td&gt;&lt;td&gt;19200&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600060005560016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;10818&lt;&#x2F;td&gt;&lt;td&gt;19200&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;To be added.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-proof&quot;&gt;Appendix: Proof&lt;&#x2F;h2&gt;
&lt;p&gt;Because the &lt;em&gt;storage slot&#x27;s original value&lt;&#x2F;em&gt; is defined as the value
when a reversion happens on the &lt;em&gt;current transaction&lt;&#x2F;em&gt;, it&#x27;s easy to
see that call frames won&#x27;t interfere &lt;code&gt;SSTORE&lt;&#x2F;code&gt; gas calculation. So
although the below proof is discussed without call frames, it applies
to all situations with call frames. We will discuss the case
separately for &lt;em&gt;original value&lt;&#x2F;em&gt; being zero and not zero, and use
&lt;em&gt;induction&lt;&#x2F;em&gt; to prove some properties of &lt;code&gt;SSTORE&lt;&#x2F;code&gt; gas cost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Final value&lt;&#x2F;em&gt; is the value of a particular storage slot at the end of
a transaction. &lt;em&gt;Absolute gas used&lt;&#x2F;em&gt; is the absolute value of &lt;em&gt;gas used&lt;&#x2F;em&gt;
minus &lt;em&gt;refund&lt;&#x2F;em&gt;. We use &lt;code&gt;N&lt;&#x2F;code&gt; to represent the total number of &lt;code&gt;SSTORE&lt;&#x2F;code&gt;
operations on a storage slot. For states discussed below, refer to
&lt;em&gt;State Transition&lt;&#x2F;em&gt; in &lt;em&gt;Explanation&lt;&#x2F;em&gt; section.&lt;&#x2F;p&gt;
&lt;p&gt;Below we do the proof under the assumption that all parameters are
unchanged, meaning &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt; is &lt;code&gt;200&lt;&#x2F;code&gt;. However, note that the proof
still applies no matter how &lt;code&gt;SLOAD_GAS&lt;&#x2F;code&gt; is changed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;original-value-being-zero&quot;&gt;Original Value Being Zero&lt;&#x2F;h3&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, we want to prove that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Case I&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up still being 0, we want to charge &lt;code&gt;200 * N&lt;&#x2F;code&gt; gases, because no disk write is needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case II&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being a non-zero value, we want to
charge &lt;code&gt;20000 + 200 * (N-1)&lt;&#x2F;code&gt; gas, because it requires writing this
slot to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;base-case&quot;&gt;Base Case&lt;&#x2F;h4&gt;
&lt;p&gt;We always start at state A. The first &lt;code&gt;SSTORE&lt;&#x2F;code&gt; can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Go to state A: 200 gas is deducted. We satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt; because
&lt;code&gt;200 * N == 200 * 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state B: 20000 gas is deducted. We satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt; because
&lt;code&gt;20000 + 200 * (N-1) == 20000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;inductive-step&quot;&gt;Inductive Step&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;From A to A. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
gas cost is &lt;code&gt;200 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From A to B. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
gas cost is &lt;code&gt;20000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From B to B. The previous gas cost is &lt;code&gt;20000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 + 20000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy
&lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From B to A. The previous gas cost is &lt;code&gt;20000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 - 19800 + 20000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy
&lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;original-value-not-being-zero&quot;&gt;Original Value Not Being Zero&lt;&#x2F;h3&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is not 0, we want to prove that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Case I&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up unchanged, we want to
charge &lt;code&gt;200 * N&lt;&#x2F;code&gt; gases, because no disk write is needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case II&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being zero, we want to
charge &lt;code&gt;5000 - 15000 + 200 * (N-1)&lt;&#x2F;code&gt; gas. Note that &lt;code&gt;15000&lt;&#x2F;code&gt; is the
refund in actual definition.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case III&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being a changed non-zero
value, we want to charge &lt;code&gt;5000 + 200 * (N-1)&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;base-case-1&quot;&gt;Base Case&lt;&#x2F;h4&gt;
&lt;p&gt;We always start at state X. The first &lt;code&gt;SSTORE&lt;&#x2F;code&gt; can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Go to state X: 200 gas is deducted. We satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt; because
&lt;code&gt;200 * N == 200 * 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state Y: 5000 gas is deducted. We satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt; because
&lt;code&gt;5000 + 200 * (N-1) == 5000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state Z: The absolute gas used is &lt;code&gt;5000 - 15000&lt;&#x2F;code&gt; where 15000
is the refund. We satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt; because &lt;code&gt;5000 - 15000 + 200 * (N-1) == 5000 - 15000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;inductive-step-1&quot;&gt;Inductive Step&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;From X to X. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current gas
cost is &lt;code&gt;200 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From X to Y. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current gas
cost is &lt;code&gt;5000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From X to Z. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
absolute gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case
II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to X. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
absolute current gas cost is &lt;code&gt;200 - 4800 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It
satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to Y. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case
III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to Z. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current absolute gas cost is &lt;code&gt;200 - 15000 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It
satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to X. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 10200 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to Y. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 15000 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to Z. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Common Prometheus Metrics Names for Clients</title>
        <published>2019-07-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Adrian Sutton</name><uri>https://github.com/ajsutton</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2159/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/common-chain-metrics/3415" />
        

        <id>https://wg-eips.ritovision.com/2159/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2159"
            label="EIP-2159" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2159/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Standardized names of common metrics for Ethereum clients to use with Prometheus, a widely used monitoring and alerting solution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Many Ethereum clients expose a range of metrics in a format compatible with Prometheus to allow operators to monitor the client&#x27;s behaviour and performance and raise alerts if the chain isn&#x27;t progressing or there are other indications of errors.
While the majority of these metrics are highly client-specific, reporting on internal implementation details of the client, some are applicable to all clients.
By standardizing the naming and format of these common metrics, operators are able to monitor the operation of multiple clients in a single dashboard or alerting configuration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Using common names and meanings for metrics which apply to all clients allows node operators to monitor clusters of nodes using heterogeneous clients using a single dashboard and alerting configuration.
Currently there are no agreed names or meanings, leaving client developers to invent their own making it difficult to monitor a heterogeneous cluster.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The table below defines metrics which may be captured by Ethereum clients which expose metrics to Prometheus. Clients may expose additional metrics however these should not use the &lt;code&gt;ethereum_&lt;&#x2F;code&gt; prefix.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Metric type&lt;&#x2F;th&gt;&lt;th&gt;Definition&lt;&#x2F;th&gt;&lt;th&gt;JSON-RPC Equivalent&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;ethereum_blockchain_height&lt;&#x2F;td&gt;&lt;td&gt;Gauge&lt;&#x2F;td&gt;&lt;td&gt;The current height of the canonical chain&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;eth_blockNumber&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ethereum_best_known_block_number&lt;&#x2F;td&gt;&lt;td&gt;Gauge&lt;&#x2F;td&gt;&lt;td&gt;The estimated highest block available&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;highestBlock&lt;&#x2F;code&gt; of &lt;code&gt;eth_syncing&lt;&#x2F;code&gt; or &lt;code&gt;eth_blockNumber&lt;&#x2F;code&gt; if not syncing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ethereum_peer_count&lt;&#x2F;td&gt;&lt;td&gt;Gauge&lt;&#x2F;td&gt;&lt;td&gt;The current number of peers connected&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;net_peerCount&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ethereum_peer_limit&lt;&#x2F;td&gt;&lt;td&gt;Gauge&lt;&#x2F;td&gt;&lt;td&gt;The maximum number of peers this node allows to connect&lt;&#x2F;td&gt;&lt;td&gt;No equivalent&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Note that &lt;code&gt;ethereum_best_known_block_number&lt;&#x2F;code&gt; always has a value. When the &lt;code&gt;eth_syncing&lt;&#x2F;code&gt; JSON-RPC method would return &lt;code&gt;false&lt;&#x2F;code&gt;, the current chain height is used.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The defined metrics are independent of Ethereum client implementation but provide sufficient information to create an overview dashboard to support monitoring a group of Ethereum nodes.&lt;&#x2F;p&gt;
&lt;p&gt;There is a similar, though more prescriptive, specification for beacon chain client metrics.
The specific details of how to expose the metrics has been omitted as there is variance in existing implementations and standardising this does not provide any significant benefit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This is &lt;em&gt;not&lt;&#x2F;em&gt; a consensus affecting change.&lt;&#x2F;p&gt;
&lt;p&gt;Clients may already be publishing these metrics using different names and changing to the new form may break existing alerts or dashboards. Clients that want to avoid this incompatibility can expose the metrics under both the old and new names.&lt;&#x2F;p&gt;
&lt;p&gt;Clients may also be publishing metrics with a different meaning using these names. Backwards compatibility cannot be preserved in this case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Pantheon switched to using these standard metric names in its 1.2 release: https:&#x2F;&#x2F;github.com&#x2F;PegaSysEng&#x2F;pantheon&#x2F;pull&#x2F;1634.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Prometheus. https:&#x2F;&#x2F;prometheus.io&lt;&#x2F;li&gt;
&lt;li&gt;Beacon chain metrics specification. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;eth2.0-metrics&#x2F;blob&#x2F;master&#x2F;metrics.md&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Consumable Interface (Tickets, etc)</title>
        <published>2019-06-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Zainan Victor Zhou</name><uri>https://github.com/xinbenlv</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2135/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2135-erc-consumable-interface/3439" />
        

        <id>https://wg-eips.ritovision.com/2135/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2135"
            label="ERC-2135" />
        

        
        

        
        <summary type="html">An interface extending ERC-721 and ERC-1155 for consumability, supporting use case such as an event ticket.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2135/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines an interface to mark a digital asset as &quot;consumable&quot; and to react to its &quot;consumption.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Digital assets sometimes need to be consumed. One of the most common examples is a concert ticket.
It is &quot;consumed&quot; when the ticket-holder enters the concert hall.&lt;&#x2F;p&gt;
&lt;p&gt;Having a standard interface enables interoperability for services, clients, UI, and inter-contract functionalities on top of this use-case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Any compliant contract &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; &amp;gt;=0.7.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.9&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ERC-165 identifier of this interface is 0xdd691946&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC2135&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The consume function consumes a token every time it succeeds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address of consumer of this token. It doesn&amp;#39;t have&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  to be the EOA or contract Account that initiates the TX.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  the NFT asset being consumed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     extra data passed in for consume for extra message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  or future extension.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; consume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _success&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface to check whether an asset is consumable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address of consumer of this token. It doesn&amp;#39;t have&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  to be the EOA or contract Account that initiates the TX.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  the NFT asset being consumed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   the amount of the asset being consumed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isConsumableBy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _consumer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _amount&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _consumable&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The event emitted when there is a successful consumption.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; consumer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address of consumer of this token. It doesn&amp;#39;t have&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  to be the EOA or contract Account that initiates the TX.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  the NFT asset being consumed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   the amount of the asset being consumed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     extra data passed in for consume for extra message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                  or future extension.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OnConsumption&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; consumer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; assetId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&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&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;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;If the compliant contract is an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; token, in addition to &lt;code&gt;OnConsumption&lt;&#x2F;code&gt;, it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; also emit the &lt;code&gt;Transfer&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; event (as applicable) as if a token has been transferred from the current holder to the zero address if the call to &lt;code&gt;consume&lt;&#x2F;code&gt; method succeeds.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;supportsInterface(0xdd691946)&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return &lt;code&gt;true&lt;&#x2F;code&gt; for any compliant contract, as per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;The function &lt;code&gt;consume&lt;&#x2F;code&gt; performs the consume action. This EIP does not assume:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;who has the power to perform consumption&lt;&#x2F;li&gt;
&lt;li&gt;under what condition consumption can occur&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It does, however, assume the asset can be identified in a &lt;code&gt;uint256&lt;&#x2F;code&gt; asset id as in the parameter. A design convention and compatibility consideration is put in place to follow the ERC-721 pattern.&lt;&#x2F;p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;The event notifies subscribers whoever are interested to learn an asset is being consumed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To keep it simple, this standard &lt;em&gt;intentionally&lt;&#x2F;em&gt; contains no functions or events related to the creation of a consumable asset. This is because the creation of a consumable asset will need to make assumptions about the nature of an actual use-case. If there are common use-cases for creation, another follow up standard can be created.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Metadata associated to the consumables is not included the standard. If necessary, related metadata can be created with a separate metadata extension interface like &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We choose to include an &lt;code&gt;address consumer&lt;&#x2F;code&gt; for &lt;code&gt;consume&lt;&#x2F;code&gt; function and &lt;code&gt;isConsumableBy&lt;&#x2F;code&gt; so that an NFT MAY be consumed for someone other than the transaction initiator.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We choose to include an extra &lt;code&gt;_data&lt;&#x2F;code&gt; field for future extension, such as
adding crypto endorsements.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We explicitly stay opinion-less about whether ERC-721 or ERC-1155 shall be required because
while we design this EIP with ERC-721 and ERC-1155 in mind mostly, we don&#x27;t want to rule out
the potential future case someone use a different token standard or use it in different use cases.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The boolean view function of &lt;code&gt;isConsumableBy&lt;&#x2F;code&gt; can be used to check whether an asset is
consumable by the &lt;code&gt;_consumer&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This interface is designed to be compatible with ERC-721 and NFT of ERC-1155. It can be tweaked to used for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; and Fungible Token of ERC-1155.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  describe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Consumption&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Should consume when minted&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; fakeTokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x1234&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; addr1&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; loadFixture&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;deployFixture&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;safeMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fakeTokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fakeTokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isConsumableBy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fakeTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; tx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;consume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fakeTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; receipt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;wait&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; events&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; receipt&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;events&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;filter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;OnConsumption&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;events&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;events&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;consumer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;events&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;assetId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fakeTokenId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;events&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;fakeTokenId&lt;&#x2F;span&gt;&lt;span&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&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;rejectedWith&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC721: invalid token ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isConsumableBy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; fakeTokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;rejectedWith&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC721: invalid token ID&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;  describe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP-165 Identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    it&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Should match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; async&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; loadFixture&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;deployFixture&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;get165&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdd691946&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdd691946&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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&gt;    }&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;)&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;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A deployment of version 0x1002 has been deployed onto &lt;code&gt;goerli&lt;&#x2F;code&gt; testnet at address &lt;code&gt;0x3682bcD67b8A5c0257Ab163a226fBe07BF46379B&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Find the reference contract verified source code on Etherscan&#x27;s
&lt;code&gt;goerli&lt;&#x2F;code&gt; site for the address above.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Compliant contracts should pay attention to the balance change when a token is consumed.
When the contract is being paused, or the user is being restricted from transferring a token,
the consumeability should be consistent with the transferral restriction.&lt;&#x2F;p&gt;
&lt;p&gt;Compliant contracts should also carefully define access control, particularly whether any EOA or contract account may or may not initiate a &lt;code&gt;consume&lt;&#x2F;code&gt; method in their own use case.&lt;&#x2F;p&gt;
&lt;p&gt;Security audits and tests should be used to verify that the access control to the &lt;code&gt;consume&lt;&#x2F;code&gt;
function behaves as expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Transaction data gas cost reduction</title>
        <published>2019-05-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alexey Akhunov</name><uri>https://github.com/AlexeyAkhunov</uri>
	</author>
	
	<author>
		<name>Eli Ben Sasson</name><email>eli@starkware.co</email>
	</author>
	
	<author>
		<name>Tom Brand</name><email>tom@starkware.co</email>
	</author>
	
	<author>
		<name>Louis Guthmann</name><email>louis@starkware.co</email>
	</author>
	
	<author>
		<name>Avihu Levy</name><email>avihu@starkware.co</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2028/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-2028-calldata-gas-cost-reduction/3280" />
        

        <id>https://wg-eips.ritovision.com/2028/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2028"
            label="EIP-2028" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2028/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;We propose to reduce the gas cost of Calldata (&lt;code&gt;GTXDATANONZERO&lt;&#x2F;code&gt;) from its current value of 68 gas per byte to 16 gas per byte, to be backed by mathematical modeling and empirical estimates. The mathematical model is the one used in the works of Sompolinsky and Zohar [1] and Pass, Seeman and Shelat [2], which relates network security to network delay. We shall (1) evaluate the theoretical impact of lower Calldata gas cost on network delay using this model, (2) validate the model empirically, and (3) base the proposed gas cost on our findings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There are a couple of main benefits to accepting this proposal and lowering gas cost of Calldata
On-Chain Scalability: Generally speaking, higher bandwidth of Calldata improves scalability, as more data can fit within a single block.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Layer two scalability: Layer two scaling solutions can improve scalability by moving storage and computation off-chain, but often introduce data transmission instead.
&lt;ul&gt;
&lt;li&gt;Proof systems such as STARKs and SNARKs use a single proof that attests to the computational integrity of a large computation, say, one that processes a large batch of transactions.&lt;&#x2F;li&gt;
&lt;li&gt;Some solutions use fraud proofs which requires a transmission of merkle proofs.&lt;&#x2F;li&gt;
&lt;li&gt;Moreover, one optional data availability solution to layer two is to place data on the main chain, via Calldata.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Stateless clients: The same model will be used to determine the price of the state access for the stateless client regime, which will be proposed in the State Rent (from version 4). There, it is expected that the gas cost of state accessing operation will increase roughly proportional to the extra bandwidth required to transmit the “block proofs” as well as extra processing required to verify those block proofs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The gas per non-zero byte is reduced from 68 to 16. Gas cost of zero bytes is unchanged.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Roughly speaking, reducing the gas cost of Calldata leads to potentially larger blocks, which increases the network delay associated with data transmission over the network. This is only part of the full network delay, other factors are block processing time (and storage access, as part of it). Increasing network delay affects security by lowering the cost of attacking the network, because at any given point in time fewer nodes are updated on the latest state of the blockchain.&lt;&#x2F;p&gt;
&lt;p&gt;Yonatan Sompolinsky and Aviv Zohar suggested in [1] an elegant model to relate network delay to network security, and this model is also used in the work of Rafael Pass, Lior Seeman and Abhi Shelat [2]. We briefly explain this model below, because we shall study it theoretically and validate it by empirical measurements to reach the suggested lower gas cost for Calldata.&lt;&#x2F;p&gt;
&lt;p&gt;The model uses the following natural parameters:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;lambda&lt;&#x2F;em&gt;  denotes the block creation rate [1&#x2F;s]: We treat the process of finding a PoW
solution as a poisson process with rate &lt;em&gt;lambda&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;beta&lt;&#x2F;em&gt; - chain growth rate [1&#x2F;s]: the rate at which new blocks are added to
the heaviest chain.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;D&lt;&#x2F;em&gt; - block delay [s]: The time that elapses between the mining of a new block and its acceptance by all the miners (all miners switched to mining on top of that block).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;beta-lower-bound&quot;&gt;&lt;em&gt;Beta&lt;&#x2F;em&gt; Lower Bound&lt;&#x2F;h3&gt;
&lt;p&gt;Notice that &lt;em&gt;lambda&lt;&#x2F;em&gt; =&amp;gt; &lt;em&gt;beta&lt;&#x2F;em&gt;, because not all blocks that are found will enter the main chain (as is the case with uncles). In [1] it was shown that for a blockchain using the longest chain rule, one may bound &lt;em&gt;beta&lt;&#x2F;em&gt; from below by &lt;em&gt;lambda&lt;&#x2F;em&gt;&#x2F; (1+ D * &lt;em&gt;lambda&lt;&#x2F;em&gt;). This lower bound holds in the extremal case where the topology of the network is a clique in which the delay between each pair of nodes is D, the maximal possible delay. Recording both the lower and upper bounds on &lt;em&gt;beta&lt;&#x2F;em&gt; we get&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_lambda_ &amp;gt;= _beta_ &amp;gt;= _lambda_ &#x2F; (1 + D * _lambda_)               (*)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice, as a sanity check, that when there is no delay (D=0) then &lt;em&gt;beta&lt;&#x2F;em&gt; equals &lt;em&gt;lambda&lt;&#x2F;em&gt;, as expected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security-of-the-network&quot;&gt;Security of the network&lt;&#x2F;h3&gt;
&lt;p&gt;An attacker attempting to reorganize the main chain needs to generate blocks at a rate that is greater than &lt;em&gt;beta&lt;&#x2F;em&gt;.
Fixing the difficulty level of the PoW puzzle, the total hash rate in the system is correlated to &lt;em&gt;lambda&lt;&#x2F;em&gt;. Thus, &lt;em&gt;beta&lt;&#x2F;em&gt; &#x2F; &lt;em&gt;lambda&lt;&#x2F;em&gt; is defined as the &lt;em&gt;efficiency&lt;&#x2F;em&gt; of the system, as it measures the fraction of total hash power that is used to generate the main chain of the network.&lt;&#x2F;p&gt;
&lt;p&gt;Rearranging (*) gives the following lower bound on efficiency in terms of delay:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_beta_ &#x2F; _lambda_ &amp;gt;= 1 &#x2F; (1 + D * _lambda_)                 (**)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-delay-parameter-d&quot;&gt;The &lt;em&gt;delay&lt;&#x2F;em&gt; parameter D&lt;&#x2F;h3&gt;
&lt;p&gt;The network delay depends on the location of the mining node within the network and on the current network topology (which changes dynamically), and consequently is somewhat difficult to measure directly.
Previously, Christian Decker and Roger Wattenhofer [3] showed that propagation time scales with blocksize,  and Vitalik Buterin showed that uncle rate, which is tightly related to efficiency (**) measure, also scales with block size [4].&lt;&#x2F;p&gt;
&lt;p&gt;However, the delay function can be decomposed into two parts D = &lt;em&gt;D_t&lt;&#x2F;em&gt; + &lt;em&gt;D_p&lt;&#x2F;em&gt;, where &lt;em&gt;D_t&lt;&#x2F;em&gt; is the delay caused by the transmission of the block and &lt;em&gt;D_p&lt;&#x2F;em&gt; is the delay caused by the processing of the block by the node. Our model and tests will examine the effect of Calldata on each of &lt;em&gt;D_t&lt;&#x2F;em&gt; and &lt;em&gt;D_p&lt;&#x2F;em&gt;, postulating that their effect is different. This may be particularly relevant for Layer 2 Scalability and for Stateless Clients (Rationales 2, 3 above) because most of the Calldata associated with these goals are Merkle authentication paths that have a large &lt;em&gt;D_t&lt;&#x2F;em&gt; component but relatively small &lt;em&gt;D_p&lt;&#x2F;em&gt; values.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;To suggest the gas cost of calldata we shall conduct two types of tests:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Network tests, conducted on the Ethereum mainnet, used to estimate the effect on increasing block size on &lt;em&gt;D_p&lt;&#x2F;em&gt; and &lt;em&gt;D_t&lt;&#x2F;em&gt;, on the overall network delay D and the efficiency ratio (**), as well as delays between different mining pools. Those tests will include regression tests on existing data, and stress tests to introduce extreme scenarios.&lt;&#x2F;li&gt;
&lt;li&gt;Local tests, conducted on a single node and measuring the processing time as a function of Calldata amount and general computation limits.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;liorgold2&#x2F;parity-ethereum&#x2F;pull&#x2F;1&quot;&gt;Parity&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;liorgold2&#x2F;go-ethereum&#x2F;pull&#x2F;1&quot;&gt;Geth&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] Yonatan Sompolinsky, Aviv Zohar: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;881.pdf&quot;&gt;Secure High-Rate Transaction Processing in Bitcoin&lt;&#x2F;a&gt;. Financial Cryptography 2015: 507-527&lt;&#x2F;p&gt;
&lt;p&gt;[2] Rafael Pass, Lior Seeman, Abhi Shelat: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;454.pdf&quot;&gt;Analysis of the Blockchain Protocol in Asynchronous Networks&lt;&#x2F;a&gt;, ePrint report 2016&#x2F;454&lt;&#x2F;p&gt;
&lt;p&gt;[3] Christian Decker, Roger Wattenhofer: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gsd.inesc-id.pt&#x2F;~ler&#x2F;docencia&#x2F;rcs1314&#x2F;papers&#x2F;P2P2013_041.pdf&quot;&gt;Information propagation in the Bitcoin network&lt;&#x2F;a&gt;. P2P 2013: 1-10&lt;&#x2F;p&gt;
&lt;p&gt;[4] Vitalik Buterin: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;10&#x2F;31&#x2F;uncle-rate-transaction-fee-analysis&#x2F;&quot;&gt;Uncle Rate and Transaction Fee Analysis&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Fork identifier for chain compatibility checks</title>
        <published>2019-05-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Péter Szilágyi</name><email>peterke@gmail.com</email>
	</author>
	
	<author>
		<name>Felix Lange</name><email>fjl@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2124/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2125" />
        

        <id>https://wg-eips.ritovision.com/2124/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:2124"
            label="EIP-2124" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2124/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Currently nodes in the Ethereum network try to find each other by establishing random connections to remote machines &quot;looking&quot; like an Ethereum node (public networks, private networks, test networks, etc), hoping that they found a useful peer (same genesis, same forks). This wastes time and resources, especially for smaller networks.&lt;&#x2F;p&gt;
&lt;p&gt;To avoid this overhead, Ethereum needs a mechanism that can precisely identify whether a node will be useful, as early as possible. Such a mechanism requires a way to summarize chain configurations, as well as a way to disseminate said summaries in the network.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal focuses only on the definition of said summary - a generally useful &lt;em&gt;fork identifier&lt;&#x2F;em&gt; - and it&#x27;s validation rules, allowing it to be embedded into arbitrary network protocols (e.g. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;778&#x2F;&quot;&gt;discovery ENRs&lt;&#x2F;a&gt; or &lt;code&gt;eth&#x2F;6x&lt;&#x2F;code&gt; handshakes).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;There are many public and private Ethereum networks, but the discovery protocol doesn&#x27;t differentiate between them. The only way to check if a peer is good or bad (same chain or not), is to establish a TCP&#x2F;IP connection, wrap it with RLPx cryptography, then execute an &lt;code&gt;eth&lt;&#x2F;code&gt; handshake. This is an extreme cost to bear if it turns out that the remote peer is on a different network and it&#x27;s not even precise enough to differentiate Ethereum and Ethereum Classic. This cost is magnified for small networks, where a lot more trial and errors are needed to find good nodes.&lt;&#x2F;p&gt;
&lt;p&gt;Even if the peer &lt;strong&gt;is&lt;&#x2F;strong&gt; on the same chain, during non-controversial consensus upgrades, not everybody updates their nodes in time (developer nodes, leftovers, etc). These stale nodes put a meaningless burden on the peer-to-peer network, since they just latch on to good nodes, but don&#x27;t accept upgraded blocks. This causes valuable peer slots and bandwidth to be lost until the stale nodes finally update. This is a serious issue for test networks, where leftovers can linger for months.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP proposes a new identity scheme to both precisely and concisely summarize the chain&#x27;s current status (genesis and all applied forks). The conciseness is particularly important to make the identity useful across datagram protocols too. The EIP solves a number of issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If two nodes are on different networks, they should never even consider connecting.&lt;&#x2F;li&gt;
&lt;li&gt;If a hard fork passes, upgraded nodes should reject non-upgraded ones, but &lt;strong&gt;NOT&lt;&#x2F;strong&gt; before.&lt;&#x2F;li&gt;
&lt;li&gt;If two chains share the same genesis, but not forks (ETH &#x2F; ETC), they should reject each other.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This EIP does not attempt to solve the clean separation of 3-way-forks! If at the same future block number, the network splits into three (non-fork, fork-A and fork-B), separating the forkers from each another will need case-by-case special handling. Not handling this keeps the proposal pragmatic, simple and also avoids making it too easy to fork off mainnet.&lt;&#x2F;p&gt;
&lt;p&gt;To keep the scope limited, this EIP only defines the identity scheme and validation rules. The same scheme and algorithm can be embedded into various networking protocols, allowing both the &lt;code&gt;eth&#x2F;6x&lt;&#x2F;code&gt; handshake to be more precise (Ethereum vs. Ethereum Classic); as well as the discovery to be more useful (reject surely peers without ever connecting).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Peer-to-peer networking is messy and hard due to firewalls and network address translation (NAT). Generally only a small fraction of nodes have publicly routed addresses and P2P networks rely mainly on these for forwarding data for everyone else. The best way to maximize the utility of the public nodes is to ensure their resources aren&#x27;t wasted on tasks that are worthless to the network.&lt;&#x2F;p&gt;
&lt;p&gt;By aggressively cutting off incompatible nodes from each other we can extract a lot more value from the public nodes, making the entire P2P network much more robust and reliable. Supporting this network partitioning at a discovery layer can further enhance performance as we avoid the costly crypto and latency&#x2F;bandwidth hit associated with establishing a stream connection in the first place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Each node maintains the following values:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_HASH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: IEEE CRC32 checksum (&lt;code&gt;[4]byte&lt;&#x2F;code&gt;) of the genesis hash and fork blocks numbers that already passed.
&lt;ul&gt;
&lt;li&gt;The fork block numbers are fed into the CRC32 checksum in ascending order.&lt;&#x2F;li&gt;
&lt;li&gt;If multiple forks are applied at the same block, the block number is checksummed only once.&lt;&#x2F;li&gt;
&lt;li&gt;Block numbers are regarded as &lt;code&gt;uint64&lt;&#x2F;code&gt; integers, encoded in big endian format when checksumming.&lt;&#x2F;li&gt;
&lt;li&gt;If a chain is configured to start with a non-Frontier ruleset already in its genesis, that is NOT considered a fork.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Block number (&lt;code&gt;uint64&lt;&#x2F;code&gt;) of the next upcoming fork, or &lt;code&gt;0&lt;&#x2F;code&gt; if no next fork is known.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;E.g. &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; for mainnet would be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;forkhash₀ = &lt;code&gt;0xfc64ec04&lt;&#x2F;code&gt; (Genesis) = &lt;code&gt;CRC32(&amp;lt;genesis-hash&amp;gt;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;forkhash₁ = &lt;code&gt;0x97c2c34c&lt;&#x2F;code&gt; (Homestead) = &lt;code&gt;CRC32(&amp;lt;genesis-hash&amp;gt; || uint64(1150000))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;forkhash₂ = &lt;code&gt;0x91d1f948&lt;&#x2F;code&gt; (DAO fork) = &lt;code&gt;CRC32(&amp;lt;genesis-hash&amp;gt; || uint64(1150000) || uint64(1920000))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;em&gt;fork identifier&lt;&#x2F;em&gt; is defined as &lt;code&gt;RLP([FORK_HASH, FORK_NEXT])&lt;&#x2F;code&gt;. This &lt;code&gt;forkid&lt;&#x2F;code&gt; is cross validated (&lt;strong&gt;NOT&lt;&#x2F;strong&gt; naively compared) to assess a remote chain&#x27;s compatibility. Irrespective of fork state, both parties must come to the same conclusion to avoid indefinite reconnect attempts from one side.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;validation-rules&quot;&gt;Validation rules&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;If local and remote &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; matches, compare local head to &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;The two nodes are in the same fork state currently. They might know of differing future forks, but that&#x27;s not relevant until the fork triggers (might be postponed, nodes might be updated to match).
&lt;ul&gt;
&lt;li&gt;1a) A remotely announced but remotely not passed block is already passed locally, disconnect, since the chains are incompatible.&lt;&#x2F;li&gt;
&lt;li&gt;1b) No remotely announced fork; or not yet passed locally, connect.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;If the remote &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; is a subset of the local past forks and the remote &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; matches with the locally following fork block number, connect.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Remote node is currently syncing. It might eventually diverge from us, but at this current point in time we don&#x27;t have enough information.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;If the remote &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; is a superset of the local past forks and can be completed with locally known future forks, connect.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Local node is currently syncing. It might eventually diverge from the remote, but at this current point in time we don&#x27;t have enough information.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Reject in all other cases.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;stale-software-examples&quot;&gt;Stale software examples&lt;&#x2F;h4&gt;
&lt;p&gt;The examples below try to exhaust the fork combination possibilities that arise when nodes do not run matching software versions, but otherwise follow the same chain (mainnet nodes, testnet nodes, etc).&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: center&quot;&gt;Past forks&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Future forks&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Head&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Remote &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Remote &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Connect&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Reason&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (1b)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Same forks, same sync state.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&amp;lt; B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (1b)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Remote is advertising a future fork, but that is uncertain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&amp;gt;= B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;No (1a)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Remote is advertising a future fork that passed locally.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (1b)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Local knows about a future fork, but that is uncertain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (1b)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Both know about a future fork, but that is uncertain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&amp;lt; B2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (1b)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Both know about differing future forks, but those are uncertain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&amp;gt;= B2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;No (1a)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Both know about differing future forks, but the remote one passed locally.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;[A,B]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (2)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Remote out of sync.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;[A,B,C]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes¹ (2)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Remote out of sync. Remote will need a software update, but we don&#x27;t know it yet.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A ⊕ B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (3)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Local out of sync.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B,C&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A ⊕ B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Yes (3)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Local out of sync. Local also knows about a future fork, but that is uncertain yet.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A ⊕ B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;No (4)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Local needs software update.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A ⊕ B ⊕ C&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;No² (4)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Local needs software update.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;[A,B]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;A&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;No (4)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;Remote needs software update.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;em&gt;Note, there&#x27;s one asymmetry in the table, marked with ¹ and ². Since we don&#x27;t have access to a remote node&#x27;s future fork list (just the next one), we can&#x27;t detect that it&#x27;s software is stale until it syncs up. This is acceptable as 1) the remote node will disconnect from us anyway, and 2) this is a temporary fluke during sync, not permanent with a leftover node.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h5 id=&quot;why-flatten-fork-hash-into-4-bytes-why-not-share-the-entire-genesis-and-fork-list&quot;&gt;Why flatten &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; into 4 bytes? Why not share the entire genesis and fork list?&lt;&#x2F;h5&gt;
&lt;p&gt;Whilst the &lt;code&gt;eth&lt;&#x2F;code&gt; devp2p protocol permits arbitrarily much data to be transmitted, the discovery protocol&#x27;s total space allowance for all ENR entries is 300 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;Reducing the &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; into a 4 bytes checksum ensures that we leave ample room in the ENR for future extensions; and 4 bytes is more than enough for arbitrarily many Ethereum networks from a (practical) collision perspective.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;why-use-ieee-crc32-as-the-checksum-instead-of-keccak256&quot;&gt;Why use IEEE CRC32 as the checksum instead of Keccak256?&lt;&#x2F;h5&gt;
&lt;p&gt;We need a mechanism that can flatten arbitrary data into 4 bytes, without ignoring any of the input. Any other checksum or hashing algorithm would work, but since nodes can lie at any time, there&#x27;s no value in cryptographic hash functions.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of just taking the first 4 bytes of a Keccak256 hash (seems odd) or XOR-ing all the 4-byte groups (messy), CRC32 is a better alternative, as this is exactly what it was designed for. IEEE CRC32 is also used by ethernet, gzip, zip, png, etc, so every programming language support should not be a problem.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;we-re-not-using-fork-next-for-much-can-t-we-get-rid-of-it-somehow&quot;&gt;We&#x27;re not using &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; for much, can&#x27;t we get rid of it somehow?&lt;&#x2F;h5&gt;
&lt;p&gt;We need to be able to differentiate whether a remote node is out of sync or whether its software is stale. Sharing only the past forks cannot tell us if the node is legitimately behind or stuck.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;why-advertise-only-one-next-fork-instead-of-hashing-all-known-future-ones-like-the-fork-hash&quot;&gt;Why advertise only one next fork, instead of &quot;hashing&quot; all known future ones like the &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt;?&lt;&#x2F;h5&gt;
&lt;p&gt;Opposed to past forks that have already passed (for us locally) and can be considered immutable, we don&#x27;t know anything about future ones. Maybe we&#x27;re out of sync or maybe the fork didn&#x27;t pass yet. If it didn&#x27;t pass yet, it might be postponed, so enforcing it would split the network apart. It could also happen that we&#x27;re not yet aware of all future forks (haven&#x27;t updated our software in a while).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP only defines an identity scheme, it does not define functional changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s a full suite of tests for all possible fork IDs that Mainnet, Ropsten, Rinkeby and Görli can advertise given the Petersburg fork cap (time of writing).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; testcase&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	head&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	want&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&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 class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	config&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ChainConfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	genesis&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; common&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	cases&lt;&#x2F;span&gt;&lt;span&gt;   [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&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&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Mainnet test cases&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 class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MainnetChainConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MainnetGenesisHash&lt;&#x2F;span&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;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&lt;&#x2F;span&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;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;fc64ec04&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1150000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unsynced&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 class=&quot;z-constant&quot;&gt;1149999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;fc64ec04&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1150000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Frontier block&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 class=&quot;z-constant&quot;&gt;1150000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97c2c34c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1920000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Homestead block&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 class=&quot;z-constant&quot;&gt;1919999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97c2c34c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1920000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Homestead block&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 class=&quot;z-constant&quot;&gt;1920000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;91d1f948&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2463000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First DAO block&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 class=&quot;z-constant&quot;&gt;2462999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;91d1f948&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2463000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last DAO block&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 class=&quot;z-constant&quot;&gt;2463000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7a64da13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2675000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Tangerine block&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 class=&quot;z-constant&quot;&gt;2674999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7a64da13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2675000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Tangerine block&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 class=&quot;z-constant&quot;&gt;2675000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Spurious block&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 class=&quot;z-constant&quot;&gt;4369999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Spurious block&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 class=&quot;z-constant&quot;&gt;4370000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Byzantium block&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Byzantium block&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 class=&quot;z-constant&quot;&gt;7280000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First and last Constantinople, first Petersburg block&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Today Petersburg block&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&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ropsten test cases&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 class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;TestnetChainConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;TestnetGenesisHash&lt;&#x2F;span&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;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&lt;&#x2F;span&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;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;30c7ddbc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unsynced, last Frontier, Homestead and first Tangerine block&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 class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;30c7ddbc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Tangerine block&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 class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63760190&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1700000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Spurious block&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 class=&quot;z-constant&quot;&gt;1699999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63760190&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1700000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Spurious block&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 class=&quot;z-constant&quot;&gt;1700000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3ea159c7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4230000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Byzantium block&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 class=&quot;z-constant&quot;&gt;4229999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3ea159c7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4230000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Byzantium block&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 class=&quot;z-constant&quot;&gt;4230000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97b544f3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4939394&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Constantinople block&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 class=&quot;z-constant&quot;&gt;4939393&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;97b544f3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4939394&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Constantinople block&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 class=&quot;z-constant&quot;&gt;4939394&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;d6e2149b&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6485846&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Petersburg block&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 class=&quot;z-constant&quot;&gt;6485845&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;d6e2149b&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6485846&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Petersburg block&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 class=&quot;z-constant&quot;&gt;6485846&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4bc66396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Istanbul block&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 class=&quot;z-constant&quot;&gt;7500000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4bc66396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Future Istanbul block&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&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rinkeby test cases&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 class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;RinkebyChainConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;RinkebyGenesisHash&lt;&#x2F;span&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;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&lt;&#x2F;span&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;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3b8e0691&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unsynced, last Frontier block&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 class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;60949295&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First and last Homestead block&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 class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8bde40dd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First and last Tangerine block&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 class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;cb3a64bb&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1035301&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Spurious block&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 class=&quot;z-constant&quot;&gt;1035300&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;cb3a64bb&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1035301&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Spurious block&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 class=&quot;z-constant&quot;&gt;1035301&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8d748b57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3660663&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Byzantium block&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 class=&quot;z-constant&quot;&gt;3660662&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8d748b57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3660663&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Byzantium block&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 class=&quot;z-constant&quot;&gt;3660663&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;e49cab14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4321234&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Constantinople block&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 class=&quot;z-constant&quot;&gt;4321233&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;e49cab14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4321234&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Constantinople block&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 class=&quot;z-constant&quot;&gt;4321234&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;afec6b27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5435345&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Petersburg block&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 class=&quot;z-constant&quot;&gt;5435344&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;afec6b27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5435345&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Petersburg block&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 class=&quot;z-constant&quot;&gt;5435345&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;cbdb8838&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Istanbul block&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 class=&quot;z-constant&quot;&gt;6000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;cbdb8838&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Future Istanbul block&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&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Goerli test cases&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 class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;GoerliChainConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		params&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;GoerliGenesisHash&lt;&#x2F;span&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;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;testcase&lt;&#x2F;span&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;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a3f5ab08&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1561651&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block&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 class=&quot;z-constant&quot;&gt;1561650&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a3f5ab08&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1561651&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Last Petersburg block&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 class=&quot;z-constant&quot;&gt;1561651&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c25efa5c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; First Istanbul block&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 class=&quot;z-constant&quot;&gt;2000000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c25efa5c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Future Istanbul block&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&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;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;Here&#x27;s a suite of tests of the different states a Mainnet node might be in and the different remote fork identifiers it might be required to validate and decide to accept or reject:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	head&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	id&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;   ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	err&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  error&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&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, remote announces the same. No future fork is announced.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, remote announces the same. Remote also announces a next fork&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; at block 0xffffffff, but that is uncertain.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint64&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, but it&amp;#39;s not yet aware of Petersburg (e.g. non updated node before the fork).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; In this case we don&amp;#39;t know if Petersburg passed yet or not.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, and it&amp;#39;s also aware of Petersburg (e.g. updated node before the fork). We&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; don&amp;#39;t know if Petersburg passed yet (will pass) or not.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet currently in Byzantium only (so it&amp;#39;s aware of Petersburg), remote announces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also Byzantium, and it&amp;#39;s also aware of some random fork (e.g. misconfigured Petersburg). As&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; neither forks passed at neither nodes, they may mismatch, but we still connect for now.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint64&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is simply out of sync, accept.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7280000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, remote announces Spurious + knowledge about Byzantium. Remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is definitely out of sync. It may or may not need the Petersburg update, we don&amp;#39;t know yet.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3edd5b10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4370000&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Byzantium, remote announces Petersburg. Local is out of sync, accept.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; out of sync. Local also knows about a future fork, but that is uncertain yet.&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 class=&quot;z-constant&quot;&gt;4369999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg. remote announces Byzantium but is not aware of further forks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Remote needs software update.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrRemoteStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, and isn&amp;#39;t aware of more forks. Remote announces Petersburg +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 0xffffffff. Local needs software update, reject.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5cddc0e1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Byzantium, and is aware of Petersburg. Remote announces Petersburg +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 0xffffffff. Local needs software update, reject.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5cddc0e1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, remote is Rinkeby Petersburg.&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 class=&quot;z-constant&quot;&gt;7987396&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;afec6b27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Petersburg, far in the future. Remote announces Gopherium (non existing fork)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; at some future block 88888888, for itself, but past block for local. Local is incompatible.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).&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 class=&quot;z-constant&quot;&gt;88888888&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;668db0af&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 88888888&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; fork) at block 7279999, before Petersburg. Local is incompatible.&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 class=&quot;z-constant&quot;&gt;7279999&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;a00bc324&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7279999&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ErrLocalIncompatibleOrStale&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s a couple of tests to verify the proper RLP encoding (since &lt;code&gt;FORK_HASH&lt;&#x2F;code&gt; is a 4 byte binary but &lt;code&gt;FORK_NEXT&lt;&#x2F;code&gt; is an 8 byte quantity):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  id&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;   ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  want&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;byte&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    common&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Hex2Bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c6840000000080&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;deadbeef&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;BADDCAFE&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    common&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Hex2Bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ca84deadbeef84baddcafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    ID&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Next&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;MaxUint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    common&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Hex2Bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ce84ffffffff88ffffffffffffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Geth: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;tree&#x2F;master&#x2F;core&#x2F;forkid&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Proxy Storage Slots</title>
        <published>2019-04-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Santiago Palladino</name><uri>https://github.com/spalladino</uri>
	</author>
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	<author>
		<name>Hadrien Croubois</name><uri>https://github.com/Amxx</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1967/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1967-standard-proxy-storage-slots/3185" />
        

        <id>https://wg-eips.ritovision.com/1967/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:1967"
            label="ERC-1967" />
        

        
        

        
        <summary type="html">A consistent location where proxies store the address of the logic contract they delegate to, as well as other proxy-specific information.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1967/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Delegating &lt;strong&gt;proxy contracts&lt;&#x2F;strong&gt; are widely used for both upgradeability and gas savings. These proxies rely on a &lt;strong&gt;logic contract&lt;&#x2F;strong&gt; (also known as implementation contract or master copy) that is called using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;. This allows proxies to keep a persistent state (storage and balance) while the code is delegated to the logic contract.&lt;&#x2F;p&gt;
&lt;p&gt;To avoid clashes in storage usage between the proxy and logic contract, the address of the logic contract is typically saved in a specific storage slot (for example &lt;code&gt;0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc&lt;&#x2F;code&gt; in OpenZeppelin contracts) guaranteed to be never allocated by a compiler. This EIP proposes a set of standard slots to store proxy information. This allows clients like block explorers to properly extract and show this information to end users, and logic contracts to optionally act upon it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Delegating proxies are widely in use, as a means to both support upgrades and reduce gas costs of deployments. Examples of these proxies are found in OpenZeppelin Contracts, Gnosis, AragonOS, Melonport, Limechain, WindingTree, Decentraland, and many others.&lt;&#x2F;p&gt;
&lt;p&gt;However, the lack of a common interface for obtaining the logic address for a proxy makes it impossible to build common tools that act upon this information.&lt;&#x2F;p&gt;
&lt;p&gt;A classic example of this is a block explorer. Here, the end user wants to interact with the underlying logic contract and not the proxy itself. Having a common way to retrieve the logic contract address from a proxy allows a block explorer to show the ABI of the logic contract and not that of the proxy. The explorer checks the storage of the contract at the distinguished slots to determine if it is indeed a proxy, in which case it shows information on both the proxy and the logic contract. As an example, this is how &lt;code&gt;0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&lt;&#x2F;code&gt; is shown on Etherscan:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1967&#x2F;.&#x2F;assets&#x2F;Sample-proxy-on-etherscan.png&quot; alt=&quot;Sample proxy on Etherscan&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Another example is logic contracts that explicitly act upon the fact that they are being proxied. This allows them to potentially trigger a code update as part of their logic. A common storage slot allows these use cases independently of the specific proxy implementation being used.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Monitoring of proxies is essential to the security of many applications. It is thus essential to have the ability to track changes to the implementation and admin slots. Unfortunately, tracking changes to storage slots is not easy. Consequently, it is recommended that any function that changes any of these slots SHOULD also emit the corresponding event. This includes initialization, from &lt;code&gt;0x0&lt;&#x2F;code&gt; to the first non-zero value.&lt;&#x2F;p&gt;
&lt;p&gt;The proposed storage slots for proxy-specific information are the following. More slots for additional information can be added in subsequent ERCs as needed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;logic-contract-address&quot;&gt;Logic contract address&lt;&#x2F;h3&gt;
&lt;p&gt;Storage slot &lt;code&gt;0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc&lt;&#x2F;code&gt;
(obtained as &lt;code&gt;bytes32(uint256(keccak256(&#x27;eip1967.proxy.implementation&#x27;)) - 1)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Holds the address of the logic contract that this proxy delegates to. SHOULD be empty if a beacon is used instead. Changes to this slot SHOULD be notified by the event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Upgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; implementation&lt;&#x2F;span&gt;&lt;span&gt;)&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;beacon-contract-address&quot;&gt;Beacon contract address&lt;&#x2F;h3&gt;
&lt;p&gt;Storage slot &lt;code&gt;0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50&lt;&#x2F;code&gt; (obtained as &lt;code&gt;bytes32(uint256(keccak256(&#x27;eip1967.proxy.beacon&#x27;)) - 1)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Holds the address of the beacon contract this proxy relies on (fallback). SHOULD be empty if a logic address is used directly instead, and should only be considered if the logic contract slot is empty. Changes to this slot SHOULD be notified by the event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BeaconUpgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; beacon&lt;&#x2F;span&gt;&lt;span&gt;)&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;Beacons are used for keeping the logic address for multiple proxies in a single location, allowing the upgrade of multiple proxies by modifying a single storage slot. A beacon contract MUST implement the function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function implementation() returns (address)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Beacon based proxy contracts do not use the logic contract slot. Instead, they use the beacon contract slot to store the address of the beacon they are attached to. In order to know the logic contract used by a beacon proxy, a client SHOULD:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Read the address of the beacon for the beacon logic storage slot;&lt;&#x2F;li&gt;
&lt;li&gt;Call the &lt;code&gt;implementation()&lt;&#x2F;code&gt; function on the beacon contract.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The result of the &lt;code&gt;implementation()&lt;&#x2F;code&gt; function on the beacon contract SHOULD NOT depend on the caller (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;admin-address&quot;&gt;Admin address&lt;&#x2F;h3&gt;
&lt;p&gt;Storage slot &lt;code&gt;0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103&lt;&#x2F;code&gt;
(obtained as &lt;code&gt;bytes32(uint256(keccak256(&#x27;eip1967.proxy.admin&#x27;)) - 1)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Holds the address that is allowed to upgrade the logic contract address for this proxy (optional). Changes to this slot SHOULD be notified by the event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AdminChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; previousAdmin&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newAdmin&lt;&#x2F;span&gt;&lt;span&gt;)&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;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardises the &lt;strong&gt;storage slot&lt;&#x2F;strong&gt; for the logic contract address, instead of a public method on the proxy contract. The rationale for this is that proxies should never expose functions to end users that could potentially clash with those of the logic contract.&lt;&#x2F;p&gt;
&lt;p&gt;Note that a clash may occur even among functions with different names, since the ABI relies on just four bytes for the function selector. This can lead to unexpected errors, or even exploits, where a call to a proxied contract returns a different value than expected, since the proxy intercepts the call and answers with a value of its own.&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;em&gt;Malicious backdoors in Ethereum proxies&lt;&#x2F;em&gt; by Nomic Labs:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Any function in the Proxy contract whose selector matches with one in the implementation contract will be called directly, completely skipping the implementation code.&lt;&#x2F;p&gt;
&lt;p&gt;Because the function selectors use a fixed amount of bytes, there will always be the possibility of a clash. This isn’t an issue for day to day development, given that the Solidity compiler will detect a selector clash within a contract, but this becomes exploitable when selectors are used for cross-contract interaction. Clashes can be abused to create a seemingly well-behaved contract that’s actually concealing a backdoor.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The fact that proxy public functions are potentially exploitable makes it necessary to standardise the logic contract address in a different way.&lt;&#x2F;p&gt;
&lt;p&gt;The main requirement for the storage slots chosen is that they must never be picked by the compiler to store any contract state variable. Otherwise, a logic contract could inadvertently overwrite this information on the proxy when writing to a variable of its own.&lt;&#x2F;p&gt;
&lt;p&gt;Solidity maps variables to storage based on the order in which they were declared, after the contract inheritance chain is linearized: the first variable is assigned the first slot, and so on. The exception is values in dynamic arrays and mappings, which are stored in the hash of the concatenation of the key and the storage slot. The Solidity development team has confirmed that the storage layout is to be preserved among new versions:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The layout of state variables in storage is considered to be part of the external interface of Solidity due to the fact that storage pointers can be passed to libraries. This means that any change to the rules outlined in this section is considered a breaking change of the language and due to its critical nature should be considered very carefully before being executed. In the event of such a breaking change, we would want to release a compatibility mode in which the compiler would generate bytecode supporting the old layout.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Vyper seems to follow the same strategy as Solidity. Note that contracts written in other languages, or directly in assembly, may incur in clashes.&lt;&#x2F;p&gt;
&lt;p&gt;They are chosen in such a way so they are guaranteed to not clash with state variables allocated by the compiler, since they depend on the hash of a string that does not start with a storage index. Furthermore, a &lt;code&gt;-1&lt;&#x2F;code&gt; offset is added so the preimage of the hash cannot be known, further reducing the chances of a possible attack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * implementation address that can be &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;. This address is stored in storage in the location specified by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1967[EIP1967], so that it doesn&amp;#39;t conflict with the storage layout of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * implementation behind the proxy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1967Proxy&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Proxy&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ERC1967Upgrade&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initializes the upgradeable proxy with an initial implementation specified by `_logic`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If `_data` is nonempty, it&amp;#39;s used as data in a delegate call to `_logic`. This will typically be an encoded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * function call, and allows initializing the storage of the proxy like a Solidity constructor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _logic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; 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 class=&quot;z-keyword&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_IMPLEMENTATION_SLOT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;eip1967.proxy.implementation&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _upgradeToAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_logic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current implementation address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _implementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; impl&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; ERC1967Upgrade&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_getImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This abstract contract provides getters and event emitting update functions for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1967[EIP1967] slots.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;abstract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1967Upgrade&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is the keccak-256 hash of &amp;quot;eip1967.proxy.rollback&amp;quot; subtracted by 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; _ROLLBACK_SLOT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Storage slot with the address of the current implementation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This is the keccak-256 hash of &amp;quot;eip1967.proxy.implementation&amp;quot; subtracted by 1, and is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * validated in the constructor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; _IMPLEMENTATION_SLOT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the implementation is upgraded.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Upgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; implementation&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current implementation address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_IMPLEMENTATION_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Stores a new address in the EIP1967 implementation slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _setImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newImplementation&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC1967: new implementation is not a contract&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_IMPLEMENTATION_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newImplementation&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Perform implementation upgrade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits an {Upgraded} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _upgradeTo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newImplementation&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        _setImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Upgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Perform implementation upgrade with additional setup call.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits an {Upgraded} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _upgradeToAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newImplementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; forceCall&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 class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        _upgradeTo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; forceCall&lt;&#x2F;span&gt;&lt;span&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&gt;            Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;functionDelegateCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits an {Upgraded} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _upgradeToAndCallSecure&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newImplementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; forceCall&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 class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; oldImplementation &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initial upgrade and setup call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        _setImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; forceCall&lt;&#x2F;span&gt;&lt;span&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&gt;            Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;functionDelegateCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Perform rollback test if not already in progress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;BooleanSlot &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; rollbackTesting &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getBooleanSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_ROLLBACK_SLOT&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;rollbackTesting&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Trigger rollback using upgradeTo from the new implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rollbackTesting&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;            Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;functionDelegateCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                newImplementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;                abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;upgradeTo(address)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; oldImplementation&lt;&#x2F;span&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;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rollbackTesting&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check rollback was effective&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;oldImplementation &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC1967Upgrade: upgrade breaks further upgrades&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Finally reset to the new implementation and log the upgrade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            _upgradeTo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newImplementation&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Storage slot with the admin of the contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This is the keccak-256 hash of &amp;quot;eip1967.proxy.admin&amp;quot; subtracted by 1, and is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * validated in the constructor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; _ADMIN_SLOT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the admin account has &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AdminChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; previousAdmin&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newAdmin&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current admin.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_ADMIN_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Stores a new address in the EIP1967 admin slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _setAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newAdmin&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newAdmin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC1967: new admin is the zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_ADMIN_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newAdmin&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Changes the admin of the proxy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits an {AdminChanged} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _changeAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newAdmin&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AdminChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_getAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; newAdmin&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _setAdmin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newAdmin&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This is bytes32(uint256(keccak256(&amp;#39;eip1967.proxy.beacon&amp;#39;)) - 1)) and is validated in the constructor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; _BEACON_SLOT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emitted when the beacon is upgraded.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BeaconUpgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; beacon&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the current beacon.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _getBeacon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_BEACON_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Stores a new beacon in the EIP1967 beacon slot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _setBeacon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newBeacon&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newBeacon&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ERC1967: new beacon is not a contract&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IBeacon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newBeacon&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;implementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;            &amp;quot;ERC1967: beacon implementation is not a contract&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        StorageSlot&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_BEACON_SLOT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newBeacon&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Perform beacon upgrade with additional setup call. &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: This upgrades the address of the beacon, it does&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Emits a {BeaconUpgraded} event.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _upgradeBeaconToAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newBeacon&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; forceCall&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 class=&quot;z-storage z-type&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 class=&quot;z-entity z-name&quot;&gt;        _setBeacon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newBeacon&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BeaconUpgraded&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newBeacon&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; forceCall&lt;&#x2F;span&gt;&lt;span&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&gt;            Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;functionDelegateCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;IBeacon&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;newBeacon&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;implementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This abstract contract provides a fallback function that delegates all calls to another contract using the EVM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * be specified by overriding the virtual {_implementation} function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * different contract through the {_delegate} function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * The success and return data of the delegated call will be returned back to the caller of the proxy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;abstract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Delegates the current call to `implementation`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This function does not return to its internal call site, it will return directly to the external caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _delegate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; implementation&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-keyword&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 class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Copy msg.data. We take full control of memory in this inline assembly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block because it will not return to Solidity code. We overwrite the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Solidity scratch pad at memory position 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Call the implementation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; out and outsize are 0 because we don&amp;#39;t know the size yet.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; implementation&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Copy the returned data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            returndatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            switch result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; delegatecall returns 0 on error.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            case &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;                revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            default &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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;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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is a virtual function that should be overridden so it returns the address to which the fallback function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * and {_fallback} should delegate.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _implementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Delegates the current call to the address returned by `_implementation()`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This function does not return to its internal call site, it will return directly to the external caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        _beforeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        _delegate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;_implementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * function in the contract matches the call data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        _fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * is empty.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-entity z-name&quot;&gt;        _fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * call, or as part of the Solidity `fallback` or `receive` functions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If overridden should call `super._beforeFallback()`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; _beforeFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Library for reading and writing primitive types to specific storage slots.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * This library helps with reading and writing to such slots without the need for inline assembly.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;library&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; StorageSlot&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddressSlot&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; BooleanSlot&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Bytes32Slot&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Uint256Slot&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns an `AddressSlot` with member `value` located at `slot`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getAddressSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;AddressSlot&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            r&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; slot&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns an `BooleanSlot` with member `value` located at `slot`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBooleanSlot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;BooleanSlot&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            r&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; slot&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns an `Bytes32Slot` with member `value` located at `slot`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getBytes32Slot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Bytes32Slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            r&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; slot&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns an `Uint256Slot` with member `value` located at `slot`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getUint256Slot&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; slot&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Uint256Slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;            r&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span&gt; slot&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC relies on the fact that the chosen storage slots are &lt;strong&gt;not&lt;&#x2F;strong&gt; to be allocated by the solidity compiler. This guarantees that an implementation contract will not accidentally overwrite any of the information required for the proxy to operate. As such, locations with a high slot number were chosen to avoid clashes with the slots allocated by the compiler. Also, locations with no known preimage were picked, to ensure that a write to mapping with a maliciously crafted key could not overwrite it.&lt;&#x2F;p&gt;
&lt;p&gt;Logic contracts that intend to modify proxy-specific information must do so deliberately (as is the case with UUPS) by writing to the specific storage slot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Fee market change for ETH 1.0 chain</title>
        <published>2019-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	<author>
		<name>Eric Conner</name><uri>https://github.com/econoar</uri>
	</author>
	
	<author>
		<name>Rick Dudley</name><uri>https://github.com/AFDudley</uri>
	</author>
	
	<author>
		<name>Matthew Slipper</name><uri>https://github.com/mslipper</uri>
	</author>
	
	<author>
		<name>Ian Norden</name><uri>https://github.com/i-norden</uri>
	</author>
	
	<author>
		<name>Abdelhamid Bakhta</name><uri>https://github.com/abdelhamidbakhta</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1559/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783" />
        

        <id>https://wg-eips.ritovision.com/1559/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:1559"
            label="EIP-1559" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1559/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A transaction pricing mechanism that includes fixed-per-block network fee that is burned and dynamically expands&#x2F;contracts block sizes to deal with transient congestion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;We introduce a new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction type, with the format &lt;code&gt;0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is a base fee per gas in protocol, which can move up or down each block according to a formula which is a function of gas used in parent block and gas target (block gas limit divided by elasticity multiplier) of parent block.
The algorithm results in the base fee per gas increasing when blocks are above the gas target, and decreasing when blocks are below the gas target.
The base fee per gas is burned.
Transactions specify the maximum fee per gas they are willing to give to miners to incentivize them to include their transaction (aka: priority fee).
Transactions also specify the maximum fee per gas they are willing to pay total (aka: max fee), which covers both the priority fee and the block&#x27;s network fee per gas (aka: base fee).
Senders will always pay the base fee per gas of the block their transaction was included in, and they will pay the priority fee per gas set in the transaction, as long as the combined amount of the two fees doesn&#x27;t exceed the transaction&#x27;s maximum fee per gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum historically priced transaction fees using a simple auction mechanism, where users send transactions with bids (&quot;gasprices&quot;) and miners choose transactions with the highest bids, and transactions that get included pay the bid that they specify. This leads to several large sources of inefficiency:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mismatch between volatility of transaction fee levels and social cost of transactions&lt;&#x2F;strong&gt;: bids to include transactions on mature public blockchains, that have enough usage so that blocks are full, tend to be extremely volatile. It&#x27;s absurd to suggest that the cost incurred by the network from accepting one more transaction into a block actually is 10x more when the cost per gas is 10 nanoeth compared to when the cost per gas is 1 nanoeth; in both cases, it&#x27;s a difference between 8 million gas and 8.02 million gas.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Needless delays for users&lt;&#x2F;strong&gt;: because of the hard per-block gas limit coupled with natural volatility in transaction volume, transactions often wait for several blocks before getting included, but this is socially unproductive; no one significantly gains from the fact that there is no &quot;slack&quot; mechanism that allows one block to be bigger and the next block to be smaller to meet block-by-block differences in demand.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Inefficiencies of first price auctions&lt;&#x2F;strong&gt;: The current approach, where transaction senders publish a transaction with a bid a maximum fee, miners choose the highest-paying transactions, and everyone pays what they bid. This is well-known in mechanism design literature to be highly inefficient, and so complex fee estimation algorithms are required. But even these algorithms often end up not working very well, leading to frequent fee overpayment.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Instability of blockchains with no block reward&lt;&#x2F;strong&gt;: In the long run, blockchains where there is no issuance (including Bitcoin and Zcash) at present intend to switch to rewarding miners entirely through transaction fees. However, there are known issues with this that likely leads to a lot of instability, incentivizing mining &quot;sister blocks&quot; that steal transaction fees, opening up much stronger selfish mining attack vectors, and more. There is at present no good mitigation for this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The proposal in this EIP is to start with a base fee amount which is adjusted up and down by the protocol based on how congested the network is. When the network exceeds the target per-block gas usage, the base fee increases slightly and when capacity is below the target, it decreases slightly. Because these base fee changes are constrained, the maximum difference in base fee from block to block is predictable. This then allows wallets to auto-set the gas fees for users in a highly reliable fashion. It is expected that most users will not have to manually adjust gas fees, even in periods of high network activity. For most users the base fee will be estimated by their wallet and a small priority fee, which compensates miners taking on orphan risk (e.g. 1 nanoeth), will be automatically set. Users can also manually set the transaction max fee to bound their total costs.&lt;&#x2F;p&gt;
&lt;p&gt;An important aspect of this fee system is that miners only get to keep the priority fee. The base fee is always burned (i.e. it is destroyed by the protocol). This ensures that only ETH can ever be used to pay for transactions on Ethereum, cementing the economic value of ETH within the Ethereum platform and reducing risks associated with miner extractable value (MEV). Additionally, this burn counterbalances Ethereum inflation while still giving the block reward and priority fee to miners. Finally, ensuring the miner of a block does not receive the base fee is important because it removes miner incentive to manipulate the fee in order to extract more fees from users.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Block validity is defined in the reference implementation below.
The &lt;code&gt;GASPRICE&lt;&#x2F;code&gt; (&lt;code&gt;0x3a&lt;&#x2F;code&gt;) opcode &lt;strong&gt;MUST&lt;&#x2F;strong&gt; return the &lt;code&gt;effective_gas_price&lt;&#x2F;code&gt; as defined in the reference implementation below.&lt;&#x2F;p&gt;
&lt;p&gt;As of &lt;code&gt;FORK_BLOCK_NUMBER&lt;&#x2F;code&gt;, a new &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; transaction is introduced with &lt;code&gt;TransactionType&lt;&#x2F;code&gt; 2.&lt;&#x2F;p&gt;
&lt;p&gt;The intrinsic cost of the new transaction is inherited from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2930&#x2F;&quot;&gt;EIP-2930&lt;&#x2F;a&gt;, specifically &lt;code&gt;21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * access list storage key count + 2400 * access list address count&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;TransactionPayload&lt;&#x2F;code&gt; for this transaction is &lt;code&gt;rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;signature_y_parity, signature_r, signature_s&lt;&#x2F;code&gt; elements of this transaction represent a secp256k1 signature over &lt;code&gt;keccak256(0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list]))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2718&#x2F;&quot;&gt;EIP-2718&lt;&#x2F;a&gt; &lt;code&gt;ReceiptPayload&lt;&#x2F;code&gt; for this transaction is &lt;code&gt;rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: &lt;code&gt;&#x2F;&#x2F;&lt;&#x2F;code&gt; is integer division, round down.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Union&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Dict&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Tuple&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Literal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; dataclasses&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; dataclass&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; field&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; abstractmethod&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransactionLegacy&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_price&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_limit&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	destination&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	amount&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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&gt;	v&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	r&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	s&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transaction2930Payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	chain_id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_price&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_limit&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	destination&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	amount&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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&gt;	access_list&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; field&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;default_factory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_y_parity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_r&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_s&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transaction2930Envelope&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;	type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Literal&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction2930Payload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Transaction2930Payload&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transaction1559Payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	chain_id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	max_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_limit&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	destination&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	amount&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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&gt;	access_list&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; field&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;default_factory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_y_parity&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_r&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature_s&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transaction1559Envelope&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;	type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Literal&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction1559Payload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Transaction1559Payload&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Transaction2718&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Union&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Transaction1559Envelope&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Transaction2930Envelope&lt;&#x2F;span&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&gt;Transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Union&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;TransactionLegacy&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Transaction2718&lt;&#x2F;span&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signer_address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	max_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_limit&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	destination&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	amount&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	payload&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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&gt;	access_list&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; field&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;default_factory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;list&lt;&#x2F;span&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	parent_hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	uncle_hashes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; field&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;default_factory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	author&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	state_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	transaction_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	transaction_receipt_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	logs_bloom&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	difficulty&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	number&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_limit&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; note the gas_limit is the gas_target * ELASTICITY_MULTIPLIER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	gas_used&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	timestamp&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	extra_data&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&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&gt;	proof_of_work&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	base_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-entity z-name&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;dataclass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Account&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	nonce&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	balance&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	storage_root&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	code_hash&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&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 class=&quot;z-constant&quot;&gt;INITIAL_BASE_FEE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;INITIAL_FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; TBD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;BASE_FEE_MAX_CHANGE_DENOMINATOR&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;ELASTICITY_MULTIPLIER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&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 class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; World&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validate_block&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		parent_gas_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ELASTICITY_MULTIPLIER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; on the fork block, don&amp;#39;t account for the ELASTICITY_MULTIPLIER to avoid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unduly halving the gas target.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; INITIAL_FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			parent_gas_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ELASTICITY_MULTIPLIER&lt;&#x2F;span&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&gt;		parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		parent_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		transactions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transactions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if the block used too much gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid block: too much gas used&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if the block changed the gas limit too much&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid block: gas limit increased too much&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid block: gas limit decreased too much&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if the gas limit is at least the minimum gas limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5000&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if the base fee is correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; INITIAL_FORK_BLOCK_NUMBER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;number&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			expected_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; INITIAL_BASE_FEE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		elif&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_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&gt;			expected_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		elif&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_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&gt;			gas_used_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			base_fee_per_gas_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; gas_used_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BASE_FEE_MAX_CHANGE_DENOMINATOR&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;			expected_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; base_fee_per_gas_delta&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;			gas_used_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			base_fee_per_gas_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; gas_used_delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; parent_gas_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BASE_FEE_MAX_CHANGE_DENOMINATOR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			expected_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parent_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; base_fee_per_gas_delta&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; expected_base_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid block: base fee not correct&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; execute transactions and do gas accounting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cumulative_transaction_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span&gt; unnormalized_transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; transactions&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Note: this validates transaction signature and chain ID which must happen before we normalize below since normalized transactions don&amp;#39;t include signature or chain ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			signer_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;validate_and_recover_signer_address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;unnormalized_transaction&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;normalize_transaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;unnormalized_transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; signer_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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			signer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;signer_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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid transaction: signer does not have enough ETH to cover attached value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the signer must be able to afford the transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ensure that the user was willing to at least pay the base fee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Prevent impossibly large numbers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Prevent impossibly large numbers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The total must be the larger of the two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_priority_fee_per_gas&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; priority fee is capped because the base fee is filled first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; signer pays both the priority fee and the base fee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			effective_gas_price&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;base_fee_per_gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; effective_gas_price&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			assert&lt;&#x2F;span&gt;&lt;span&gt; signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid transaction: signer does not have enough ETH to cover gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;execute_transaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; effective_gas_price&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			gas_refund&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			cumulative_transaction_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; signer gets refunded for unused gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			signer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; gas_refund&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; effective_gas_price&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;			#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; miner only receives the priority fee; note that the base fee is not given to anyone (it is burned)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;			self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;author&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; priority_fee_per_gas&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; check if the block spent too much gas transactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		assert&lt;&#x2F;span&gt;&lt;span&gt; cumulative_transaction_gas_used&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_used&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid block: gas_used does not equal total gas used in all transactions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: verify account balances match block&amp;#39;s account balances (via state root comparison)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: validate the rest of the block&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 class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; normalize_transaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; signer_address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; legacy transactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; TransactionLegacy&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				signer_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; signer_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 class=&quot;z-variable&quot;&gt;				signer_nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_price&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_price&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				destination&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;destination&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;				payload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				access_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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&gt;			)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2930 transactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Transaction2930Envelope&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				signer_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; signer_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 class=&quot;z-variable&quot;&gt;				signer_nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_price&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_price&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				destination&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;destination&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;				payload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				access_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;access_list&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1559 transactions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;transaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Transaction1559Envelope&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				signer_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; signer_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 class=&quot;z-variable&quot;&gt;				signer_nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;signer_nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				gas_limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_limit&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_priority_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				max_fee_per_gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_fee_per_gas&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				destination&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;destination&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				amount&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;				payload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;				access_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;payload&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;access_list&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;			raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;invalid transaction: unexpected number of items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&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 class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; block_hash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&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 class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transactions&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Sequence&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Transaction&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;	#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; effective_gas_price is the value returned by the GASPRICE (0x3a) opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; execute_transaction&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; NormalizedTransaction&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; effective_gas_price&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&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 class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; validate_and_recover_signer_address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; transaction&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Transaction&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&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 class=&quot;z-entity z-name&quot;&gt;	@&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Account&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Legacy Ethereum transactions will still work and be included in blocks, but they will not benefit directly from the new pricing system.  This is due to the fact that upgrading from legacy transactions to new transactions results in the legacy transaction&#x27;s &lt;code&gt;gas_price &lt;&#x2F;code&gt; entirely being consumed either by the &lt;code&gt;base_fee_per_gas&lt;&#x2F;code&gt; and the &lt;code&gt;priority_fee_per_gas&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-hash-changing&quot;&gt;Block Hash Changing&lt;&#x2F;h3&gt;
&lt;p&gt;The datastructure that is passed into keccak256 to calculate the block hash is changing, and all applications that are validating blocks are valid or using the block hash to verify block contents will need to be adapted to support the new datastructure (one additional item).  If you only take the block header bytes and hash them you should still correctly get a hash, but if you construct a block header from its constituent elements you will need to add in the new one at the end.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gasprice&quot;&gt;GASPRICE&lt;&#x2F;h3&gt;
&lt;p&gt;Previous to this change, &lt;code&gt;GASPRICE&lt;&#x2F;code&gt; represented both the ETH paid by the signer per gas for a transaction as well as the ETH received by the miner per gas.  As of this change, &lt;code&gt;GASPRICE&lt;&#x2F;code&gt; now only represents the amount of ETH paid by the signer per gas, and the amount a miner was paid for the transaction is no longer accessible directly in the EVM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;increased-max-block-size-complexity&quot;&gt;Increased Max Block Size&#x2F;Complexity&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP will increase the maximum block size, which could cause problems if miners are unable to process a block fast enough as it will force them to mine an empty block.  Over time, the average block size should remain about the same as without this EIP, so this is only an issue for short term size bursts.  It is possible that one or more clients may handle short term size bursts poorly and error (such as out of memory or similar) and client implementations should make sure their clients can appropriately handle individual blocks up to max size.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transaction-ordering&quot;&gt;Transaction Ordering&lt;&#x2F;h3&gt;
&lt;p&gt;With most people not competing on priority fees and instead using a baseline fee to get included, transaction ordering now depends on individual client internal implementation details such as how they store the transactions in memory.  It is recommended that transactions with the same priority fee be sorted by time the transaction was received to protect the network from spamming attacks where the attacker throws a bunch of transactions into the pending pool in order to ensure that at least one lands in a favorable position.  Miners should still prefer higher gas premium transactions over those with a lower gas premium, purely from a selfish mining perspective.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;miners-mining-empty-blocks&quot;&gt;Miners Mining Empty Blocks&lt;&#x2F;h3&gt;
&lt;p&gt;It is possible that miners will mine empty blocks until such time as the base fee is very low and then proceed to mine half full blocks and revert to sorting transactions by the priority fee.  While this attack is possible, it is not a particularly stable equilibrium as long as mining is decentralized.  Any defector from this strategy will be more profitable than a miner participating in the attack for as long as the attack continues (even after the base fee reached 0).  Since any miner can anonymously defect from a cartel, and there is no way to prove that a particular miner defected, the only feasible way to execute this attack would be to control 50% or more of hashing power.  If an attacker had exactly 50% of hashing power, they would make no Ether from priority fee while defectors would make double the Ether from priority fees.  For an attacker to turn a profit, they need to have some amount over 50% hashing power, which means they can instead execute double spend attacks or simply ignore any other miners which is a far more profitable strategy.&lt;&#x2F;p&gt;
&lt;p&gt;Should a miner attempt to execute this attack, we can simply increase the elasticity multiplier (currently 2x) which requires they have even more hashing power available before the attack can even be theoretically profitable against defectors.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eth-burn-precludes-fixed-supply&quot;&gt;ETH Burn Precludes Fixed Supply&lt;&#x2F;h3&gt;
&lt;p&gt;By burning the base fee, we can no longer guarantee a fixed Ether supply.  This could result in economic instability as the long term supply of ETH will no longer be constant over time.  While a valid concern, it is difficult to quantify how much of an impact this will have.  If more is burned on base fee than is generated in mining rewards then ETH will be deflationary and if more is generated in mining rewards than is burned then ETH will be inflationary.  Since we cannot control user demand for block space, we cannot assert at the moment whether ETH will end up inflationary or deflationary, so this change causes the core developers to lose some control over Ether&#x27;s long term quantity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Add `blockHash` to defaultBlock methods</title>
        <published>2019-04-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Charles Cooper</name><uri>https://github.com/charles-cooper</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1898/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1898-add-blockhash-option-to-json-rpc-methods-that-currently-support-defaultblock-parameter/11757" />
        

        <id>https://wg-eips.ritovision.com/1898/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:1898"
            label="EIP-1898" />
        

        
        

        
        <summary type="html">Add `blockHash` option to JSON-RPC methods that currently support defaultBlock parameter.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1898/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;For JSON-RPC methods which currently accept a default block parameter, additionally allow the parameter to be a block hash.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP can be considered a generalization of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;234&#x2F;&quot;&gt;EIP-234&lt;&#x2F;a&gt;. It would enable clients to unambiguously specify the block they want to query for certain JSON-RPC methods, even if the block is not in the canonical chain. This allows clients to maintain a coherent picture of blockchain state that they are interested in, even in the presence of reorgs, without requiring that the node maintain a persistent connection with the client or store any client-specific state.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The following JSON-RPC methods are affected:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eth_getBalance&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getTransactionCount&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getCode&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_call&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getProof&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following options, quoted from the Ethereum JSON-RPC spec, are currently possible for the defaultBlock parameter:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;HEX String - an integer block number&lt;&#x2F;li&gt;
&lt;li&gt;String &quot;earliest&quot; for the earliest&#x2F;genesis block&lt;&#x2F;li&gt;
&lt;li&gt;String &quot;latest&quot; - for the latest canonical block&lt;&#x2F;li&gt;
&lt;li&gt;String &quot;pending&quot; - for the pending state&#x2F;transactions&lt;&#x2F;li&gt;
&lt;li&gt;String &quot;safe&quot; - for the most recent safe block&lt;&#x2F;li&gt;
&lt;li&gt;String &quot;finalized&quot; - for the most recent finalized block&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Since there is no way to clearly distinguish between a DATA parameter and a QUANTITY parameter, this EIP proposes a new scheme for the block parameter. The following option is additionally allowed:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;OBJECT
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blockNumber&lt;&#x2F;code&gt;: QUANTITY - a block number&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;blockHash&lt;&#x2F;code&gt;: DATA - a block hash&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If the block is not found, the callee SHOULD raise a JSON-RPC error (the recommended error code is &lt;code&gt;-32001: Resource not found&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;If the tag is &lt;code&gt;blockHash&lt;&#x2F;code&gt;, an additional boolean field may be supplied to the block parameter, &lt;code&gt;requireCanonical&lt;&#x2F;code&gt;, which defaults to &lt;code&gt;false&lt;&#x2F;code&gt; and defines whether the block must be a canonical block according to the callee. If &lt;code&gt;requireCanonical&lt;&#x2F;code&gt; is &lt;code&gt;false&lt;&#x2F;code&gt;, the callee should raise a JSON-RPC error only if the block is not found (as described above). If &lt;code&gt;requireCanonical&lt;&#x2F;code&gt; is &lt;code&gt;true&lt;&#x2F;code&gt;, the callee SHOULD additionally raise a JSON-RPC error if the block is not in the canonical chain (the recommended error code is &lt;code&gt;-32000: Invalid input&lt;&#x2F;code&gt; and in any case should be different than the error code for the block not found case so that the caller can distinguish the cases). The block-not-found check SHOULD take precedence over the block-is-canonical check, so that if the block is not found the callee raises block-not-found rather than block-not-canonical.&lt;&#x2F;p&gt;
&lt;p&gt;To maintain backwards compatibility, the block number MAY be specified either as a hex string or using the new block parameter scheme. In other words, the following are equivalent for the default block parameter:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&quot;earliest&quot;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&quot;0x0&quot;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;{ &quot;blockNumber&quot;: &quot;0x0&quot; }&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;{ &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot; }&lt;&#x2F;code&gt; (hash of the genesis block on the Ethereum main chain)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;{ &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot;, &quot;requireCanonical&quot;: true }&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;{ &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot;, &quot;requireCanonical&quot;: false }&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, the state-querying JSON-RPC methods specified above have no option to unambiguously specify which block to query the state for. This can cause issues for applications which need to make multiple calls to the RPC. For instance, a wallet which just executed a transfer may want to display the balances of both the sender and recipient. If there is a re-org in between when the balance of the sender is queried via &lt;code&gt;eth_getBalance&lt;&#x2F;code&gt; and when the balance of the recipient is queried, the balances may not reconcile. As a slightly more complicated example, the UI for a decentralized exchange (which hosts orders on-chain) may walk a list of orders by calling &lt;code&gt;eth_call&lt;&#x2F;code&gt; for each of them to get the order data. Another type of use case is where an application needs to make a decision based on multiple pieces of state, e.g. a payout predicated on simultaneous ownership of two NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;In order to ensure that the state is coherent (i.e., &lt;code&gt;eth_call&lt;&#x2F;code&gt; was called with exactly the same block for every call), the application may currently use one of several strategies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Decide on a block number to use (e.g., the latest block number known to the application). After each &lt;code&gt;eth_call&lt;&#x2F;code&gt; using that block number, call &lt;code&gt;eth_getBlockByNumber&lt;&#x2F;code&gt;, also with that block number. If the block hash does not match the known hash for that block number, rollback the current activity and retry from the beginning. This adds &lt;code&gt;O(n)&lt;&#x2F;code&gt; invocations as baseline overhead and another &lt;code&gt;O(n)&lt;&#x2F;code&gt; invocations for every retry needed. Moreover, there is no way to detect the (unlikely but possible) case that the relevant block was reorged out before &lt;code&gt;eth_call&lt;&#x2F;code&gt;, and then reorged back in before &lt;code&gt;eth_getBlockByNumber&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Rely on logs, which &lt;em&gt;can&lt;&#x2F;em&gt; be queried unambiguously thanks to the &lt;code&gt;blockHash&lt;&#x2F;code&gt; parameter. However, this requires semantic support from the smart contract; if the smart contract does not emit appropriate events, the client will not be able to reconstruct the specific state it is interested in.&lt;&#x2F;li&gt;
&lt;li&gt;Rely on non-standard extensions like &lt;code&gt;parity_subscribe&lt;&#x2F;code&gt;. This requires a persistent connection between the client and node (via IPC or websockets), increases coupling between the client and the node, and cannot handle use cases where there are dependencies between invocations of &lt;code&gt;eth_call&lt;&#x2F;code&gt;, for example, walking a linked list.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Allowing &lt;code&gt;eth_call&lt;&#x2F;code&gt; and friends to unambiguously specify the block to be queried give the application developer a robust and intuitive way to solve these problems. Multiple sequential queries will query the same state, enabling the application developer to not worry about inconsistencies in their view of the blockchain state.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Backwards compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockNumber&quot;: &quot;0x0&quot; }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in genesis block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot; }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in genesis block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot;, &quot;requireCanonical&quot;: false }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in genesis block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3&quot;, &quot;requireCanonical&quot;: true }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in genesis block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-existent-block-hash&amp;gt;&quot; }&lt;&#x2F;code&gt; -&amp;gt; raise block-not-found error&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-existent-block-hash&amp;gt;&quot;, &quot;requireCanonical&quot;: false }&lt;&#x2F;code&gt; -&amp;gt; raise block-not-found error&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-existent-block-hash&amp;gt;&quot;, &quot;requireCanonical&quot;: true }&lt;&#x2F;code&gt; -&amp;gt; raise block-not-found error&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-canonical-block-hash&amp;gt;&quot; }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in specified block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-canonical-block-hash&amp;gt;&quot;, &quot;requireCanonical&quot;: false }&lt;&#x2F;code&gt; -&amp;gt; return storage at given address in specified block&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eth_getStorageAt [ &quot;0x&amp;lt;address&amp;gt;&quot;, { &quot;blockHash&quot;: &quot;0x&amp;lt;non-canonical-block-hash&amp;gt;&quot;, &quot;requireCanonical&quot;: true }&lt;&#x2F;code&gt; -&amp;gt; raise block-not-canonical error&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;None&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Repricing for trie-size-dependent opcodes</title>
        <published>2019-03-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Martin Holst Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1884/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/opcode-repricing/3024" />
        

        <id>https://wg-eips.ritovision.com/1884/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1884"
            label="EIP-1884" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1884/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes repricing certain opcodes, to obtain a good balance between gas expenditure and resource consumption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The growth of the Ethereum state has caused certain opcodes to be more resource-intensive at this point than
they were previously. This EIP proposes to raise the &lt;code&gt;gasCost&lt;&#x2F;code&gt; for those opcodes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;An imbalance between the price of an operation and the resource consumption (CPU time, memory etc)
has several drawbacks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It could be used for attacks, by filling blocks with underpriced operations which causes excessive block processing time.&lt;&#x2F;li&gt;
&lt;li&gt;Underpriced opcodes cause a skewed block gas limit, where sometimes blocks finish quickly but other blocks with similar gas use finish slowly.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If operations are well-balanced, we can maximise the block gaslimit and have a more stable processing time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;At block &lt;code&gt;N&lt;&#x2F;code&gt;,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;SLOAD&lt;&#x2F;code&gt; (&lt;code&gt;0x54&lt;&#x2F;code&gt;) operation changes from &lt;code&gt;200&lt;&#x2F;code&gt; to &lt;code&gt;800&lt;&#x2F;code&gt; gas,&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;BALANCE&lt;&#x2F;code&gt; (&lt;code&gt;0x31&lt;&#x2F;code&gt;) operation changes from &lt;code&gt;400&lt;&#x2F;code&gt; to &lt;code&gt;700&lt;&#x2F;code&gt; gas,&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; (&lt;code&gt;0x3F&lt;&#x2F;code&gt;) operation changes from &lt;code&gt;400&lt;&#x2F;code&gt; to &lt;code&gt;700&lt;&#x2F;code&gt; gas,&lt;&#x2F;li&gt;
&lt;li&gt;A new opcode, &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; is introduced at &lt;code&gt;0x47&lt;&#x2F;code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; pops &lt;code&gt;0&lt;&#x2F;code&gt; arguments off the stack,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; pushes the &lt;code&gt;balance&lt;&#x2F;code&gt; of the current address to the stack,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; is priced as &lt;code&gt;GasFastStep&lt;&#x2F;code&gt;, at &lt;code&gt;5&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Here are two charts, taken from a full sync using Geth. The execution time was measured for every opcode, and aggregated for 10K blocks. These bar charts show the top 25 &#x27;heavy&#x27; opcodes in the ranges 5M to 6M and 6M to 7M:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;.&#x2F;assets&#x2F;run3.total-bars-5.png&quot; alt=&quot;bars1&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;.&#x2F;assets&#x2F;run3.total-bars-6.png&quot; alt=&quot;bars2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note: It can also be seen that the &lt;code&gt;SLOAD&lt;&#x2F;code&gt; moves towards the top position. The &lt;code&gt;GASPRICE&lt;&#x2F;code&gt; (&lt;code&gt;0x3a&lt;&#x2F;code&gt;) opcode has position one which I believe can be optimized away within the client -- which is not the case with &lt;code&gt;SLOAD&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is another chart, showing a full sync with Geth. It represents the blocks &lt;code&gt;0&lt;&#x2F;code&gt; to &lt;code&gt;5.7M&lt;&#x2F;code&gt;, and highlights what the block processing time is spent on.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;.&#x2F;assets&#x2F;geth_processing.png&quot; alt=&quot;geth&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can be seen that &lt;code&gt;storage_reads&lt;&#x2F;code&gt; and &lt;code&gt;account_reads&lt;&#x2F;code&gt; are the two most significant factors contributing to the block processing time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sload&quot;&gt;&lt;code&gt;SLOAD&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;SLOAD&lt;&#x2F;code&gt; was repriced at &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt;, from &lt;code&gt;50&lt;&#x2F;code&gt; to &lt;code&gt;200&lt;&#x2F;code&gt;.
The following graph shows a go-ethereum full sync, where each data point represents
10K blocks. During those 10K blocks, the execution time for the opcode was aggregated.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;.&#x2F;assets&#x2F;SLOAD-run3.png&quot; alt=&quot;graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can be seen that the repricing at &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt; caused a steep drop, from around &lt;code&gt;67&lt;&#x2F;code&gt; to &lt;code&gt;23&lt;&#x2F;code&gt;.
Around block &lt;code&gt;5M&lt;&#x2F;code&gt;, it started reaching pre-&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt; levels, and at block &lt;code&gt;7M&lt;&#x2F;code&gt;
it was averaging on around &lt;code&gt;150&lt;&#x2F;code&gt; - more than double pre-eip-150 levels.&lt;&#x2F;p&gt;
&lt;p&gt;Increasing the cost of &lt;code&gt;SLOAD&lt;&#x2F;code&gt; by &lt;code&gt;4&lt;&#x2F;code&gt; would bring it back down to around &lt;code&gt;40&lt;&#x2F;code&gt;.
It is to be expected that it will rise again in the future, and may need future repricing, unless
state clearing efforts are implemented before that happens.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;balance&quot;&gt;&lt;code&gt;BALANCE&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;BALANCE&lt;&#x2F;code&gt; (a.k.a &lt;code&gt;EXTBALANCE&lt;&#x2F;code&gt;) is an operation which fetches data from the state trie. It was repriced at &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt; from &lt;code&gt;20&lt;&#x2F;code&gt; to &lt;code&gt;400&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;.&#x2F;assets&#x2F;BALANCE-run3.png&quot; alt=&quot;graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is comparable to &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; and &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;, which are priced at &lt;code&gt;700&lt;&#x2F;code&gt; already.&lt;&#x2F;p&gt;
&lt;p&gt;It has a built-in high variance, since it is often used for checking the balance of &lt;code&gt;this&lt;&#x2F;code&gt;,
which is an inherently cheap operation, however, it can be used to lookup the balance of arbitrary account which often require trie (disk) access.&lt;&#x2F;p&gt;
&lt;p&gt;In hindsight, it might have been a better choice to have two
opcodes: &lt;code&gt;EXTBALANCE(address)&lt;&#x2F;code&gt; and &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt;, and have two different prices.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This EIP proposes to extend the current opcode set.
&lt;ul&gt;
&lt;li&gt;Unfortunately, the opcode span &lt;code&gt;0x3X&lt;&#x2F;code&gt; is already full, hence the suggestion to place &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; in the &lt;code&gt;0x4X&lt;&#x2F;code&gt; range.&lt;&#x2F;li&gt;
&lt;li&gt;As for why it is priced at &lt;code&gt;5&lt;&#x2F;code&gt; (&lt;code&gt;GasFastStep&lt;&#x2F;code&gt;) instead of &lt;code&gt;2&lt;&#x2F;code&gt; (&lt;code&gt;GasQuickStep&lt;&#x2F;code&gt;), like other similar operations: the EVM execution engine still needs a lookup into the (cached) trie, and &lt;code&gt;balance&lt;&#x2F;code&gt;, unlike &lt;code&gt;gasPrice&lt;&#x2F;code&gt; or &lt;code&gt;timeStamp&lt;&#x2F;code&gt;, is not constant during the execution, so it has a bit more inherent overhead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;extcodehash&quot;&gt;&lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; was introduced in Constantinople, with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1052&#x2F;&quot;&gt;EIP-1052&lt;&#x2F;a&gt;. It was priced at &lt;code&gt;400&lt;&#x2F;code&gt; with the reasoning:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The gas cost is the same as the gas cost for the &lt;code&gt;BALANCE&lt;&#x2F;code&gt; opcode because the execution of the &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; requires the same account lookup as in &lt;code&gt;BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ergo, if we increase &lt;code&gt;BALANCE&lt;&#x2F;code&gt;, we should also increase &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The changes require a hardfork. The changes have the following consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Certain calls will become more expensive.&lt;&#x2F;li&gt;
&lt;li&gt;Default-functions which access the storage and may in some cases require more than&lt;code&gt;2300&lt;&#x2F;code&gt; gas (the minimum gas that is always available in calls).&lt;&#x2F;li&gt;
&lt;li&gt;Contracts that assume a certain fixed gas cost for calls (or internal sections) may cease to function.
&lt;ul&gt;
&lt;li&gt;A fixed gas cost is specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; and implementations of this interface do use the affected opcodes.
&lt;ul&gt;
&lt;li&gt;The ERC-165 method &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; must return a &lt;code&gt;bool&lt;&#x2F;code&gt; and use at most &lt;code&gt;30,000&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;The two example implementations from the EIP were, at the time of writing
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;586&lt;&#x2F;code&gt; gas for any input, and&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;236&lt;&#x2F;code&gt; gas, but increases linearly with a higher number of supported interfaces&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;It is unlikely that any ERC-165 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; implementation will go above &lt;code&gt;30.000&lt;&#x2F;code&gt; gas. That would require that the second variant is used, and thirty:ish interfaces are supported.&lt;&#x2F;li&gt;
&lt;li&gt;However, these operations have already been repriced earlier, so there is a historical precedent that &#x27;the gascost for these operations may change&#x27;, which should have prevented such fixed-gas-cost assumptions from being implemented.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I expect that certain patterns will be less used, for example the use of multiple modifiers which &lt;code&gt;SLOAD&lt;&#x2F;code&gt;s the same opcode will be merged into one. It may also lead to less &lt;code&gt;log&lt;&#x2F;code&gt; operations containing &lt;code&gt;SLOAD&lt;&#x2F;code&gt;ed values that are not strictly necessary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Testcases that should be implemented:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Test that &lt;code&gt;selfbalance == balance(address)&lt;&#x2F;code&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;Test that &lt;code&gt;balance(this)&lt;&#x2F;code&gt; costs as before,&lt;&#x2F;li&gt;
&lt;li&gt;Test that &lt;code&gt;selfbalance&lt;&#x2F;code&gt; does not pop from stack&lt;&#x2F;li&gt;
&lt;li&gt;Gascost verification of &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; and &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Verify that &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt; is invalid before Istanbul&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some testcases have been implemented as statetests at https:&#x2F;&#x2F;github.com&#x2F;holiman&#x2F;IstanbulTests&#x2F;tree&#x2F;master&#x2F;GeneralStateTests&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP has not yet been implemented in any client.
Both these opcodes have been repriced before, and the client internals for managing reprices are already in place.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;selfbalance&quot;&gt;&lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This is the implementation for the new opcode in go-ethereum:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; opSelfBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;pc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interpreter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;EVMInterpreter&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Stack&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;	stack&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;interpreter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;intPool&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;interpreter&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;evm&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;StateDB&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;GetBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security considerations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;See backwards compatibility section.&lt;&#x2F;li&gt;
&lt;li&gt;There are no special edgecases regarding &lt;code&gt;SELFBALANCE&lt;&#x2F;code&gt;, if we define it as &lt;code&gt;BALANCE&lt;&#x2F;code&gt; with &lt;code&gt;address&lt;&#x2F;code&gt; instead of popping an address from the stack -- since &lt;code&gt;BALANCE&lt;&#x2F;code&gt; is already well-defined.&lt;&#x2F;li&gt;
&lt;li&gt;It should be investigated if Solidity contains any hardcoded expectations on the gas cost of these operations.&lt;&#x2F;li&gt;
&lt;li&gt;In many cases, a recipient of &lt;code&gt;ether&lt;&#x2F;code&gt; from a &lt;code&gt;CALL&lt;&#x2F;code&gt; will want to issue a &lt;code&gt;LOG&lt;&#x2F;code&gt;. The &lt;code&gt;LOG&lt;&#x2F;code&gt; operation costs &lt;code&gt;375&lt;&#x2F;code&gt; plus &lt;code&gt;375&lt;&#x2F;code&gt; per topic. If the &lt;code&gt;LOG&lt;&#x2F;code&gt; also wants to do an &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, this change may make some such transfers fail.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Compact Signature Representation</title>
        <published>2019-03-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Richard Moore</name><uri>https://github.com/ricmoo</uri>
	</author>
	
	<author>
		<name>Nick Johnson</name><email>nick@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2098/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2440" />
        

        <id>https://wg-eips.ritovision.com/2098/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:2098"
            label="ERC-2098" />
        

        
        

        
        <summary type="html">A compact representation of an Ethereum Signature.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2098/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The secp256k1 curve permits the computation of the public key of signed
digest when coupled with a signature, which is used implicitly to
establish the origin of a transaction from an Externally Owned Account
as well as on-chain in EVM contracts for example, in meta-transactions and
multi-sig contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Currently signatures require 65 bytes to represent, which when aligned
to 256-bit words, requires 96 bytes (with 31 zero bytes injected). The
yParity in RLP-encoded transactions also require (on average) 1.5 bytes.
With compact signatures, this can be reduced to 64 bytes, which remains 64
bytes when word-aligned, and in the case of RLP-encoded transactions
saves the 1.5 bytes required for the yParity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The motivations for a compact representation are to simplify handling
transactions in client code, reduce gas costs and reduce transaction sizes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;A secp256k1 signature is made up of 3 parameters, &lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; and &lt;code&gt;yParity&lt;&#x2F;code&gt;.
The &lt;code&gt;r&lt;&#x2F;code&gt; represents the &lt;code&gt;x&lt;&#x2F;code&gt; component on the curve (from which the &lt;code&gt;y&lt;&#x2F;code&gt; can be
computed), and the &lt;code&gt;s&lt;&#x2F;code&gt; represents the challenge solution for signing by a
private key. Due to the symmetric nature of an elliptic curve, a &lt;code&gt;yParity&lt;&#x2F;code&gt;
is required, which indicates which of the 2 possible solutions was intended,
by indicating its parity (odd-ness).&lt;&#x2F;p&gt;
&lt;p&gt;Two key observations are required to create a compact representation.&lt;&#x2F;p&gt;
&lt;p&gt;First, the &lt;code&gt;yParity&lt;&#x2F;code&gt; parameter is always either 0 or 1 (canonically the values
used have historically been 27 and 28, as these values didn&#x27;t collide with other
binary prefixes used in Bitcoin).&lt;&#x2F;p&gt;
&lt;p&gt;Second, the top bit of the &lt;code&gt;s&lt;&#x2F;code&gt; parameters is &lt;strong&gt;always&lt;&#x2F;strong&gt; 0, due to the use of
canonical signatures which flip the solution parity to prevent negative values,
which was introduced as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2&#x2F;&quot;&gt;a constraint in Homestead&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So, we can hijack the top bit in the &lt;code&gt;s&lt;&#x2F;code&gt; parameter to store the value of
&lt;code&gt;yParity&lt;&#x2F;code&gt;, resulting in:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[256-bit r value][1-bit yParity value][255-bit s value]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;example-implementation-in-python&quot;&gt;Example Implementation In Python&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Assume yParity is 0 or 1, normalized from the canonical 27 or 28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; to_compact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; s&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; yParity&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;yParityAndS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;yParity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; s&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 class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; to_canonical&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; yParityAndS&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; yParityAndS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;yParity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;yParityAndS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The compact representation proposed is simple to both compose and decompose
in clients and in Solidity, so that it can be easily (and intuitively) supported,
while reducing transaction sizes and gas costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The Compact Representation does not collide with canonical signature as
it uses 2 parameters (r, yParityAndS) and is 64 bytes long while canonical
signatures involve 3 separate parameters (r, s, yParity) and are 65 bytes long.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Private Key: 0x1234567890123456789012345678901234567890123456789012345678901234&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Message: &amp;quot;Hello World&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signature:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  r:  0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  s:  0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  v:  27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Compact Signature:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  r:           0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  yParityAndS: 0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Private Key: 0x1234567890123456789012345678901234567890123456789012345678901234&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Message: &amp;quot;It&amp;#39;s a small(er) world&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signature:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  r:  0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  s:  0x139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  v:  28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Compact Signature:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  r:           0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  yParityAndS: 0x939c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The ethers.js library &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethers-io&#x2F;ethers.js&#x2F;blob&#x2F;ethers-v5-beta&#x2F;packages&#x2F;bytes&#x2F;src.ts&#x2F;index.ts#L323&quot;&gt;supports this in v5&lt;&#x2F;a&gt;
as an unofficial property of split signatures (i.e. &lt;code&gt;sig._vs&lt;&#x2F;code&gt;), but should be
considered an internal property that may change at discretion of the community
and any changes to this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;There are no additional security concerns introduced by this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Pseudo-introspection Registry Contract</title>
        <published>2019-03-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Jordi Baylina</name><email>jordi@baylina.cat</email>
	</author>
	
	<author>
		<name>Jacques Dafflon</name><email>mail@0xjac.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1820/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/pull/1820" />
        

        <id>https://wg-eips.ritovision.com/1820/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1820"
            label="ERC-1820" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1820/">&lt;blockquote&gt;
&lt;p&gt;:information_source: &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; has superseded &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;.&lt;&#x2F;strong&gt; :information_source:&lt;br &#x2F;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; fixes the incompatibility in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; logic which was introduced by the Solidity 0.5 update.&lt;br &#x2F;&gt;
Have a look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-464109166&quot;&gt;official announcement&lt;&#x2F;a&gt;, and the comments about the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-452465748&quot;&gt;bug&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-454021564&quot;&gt;fix&lt;&#x2F;a&gt;.&lt;br &#x2F;&gt;
Apart from this fix, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; is functionally equivalent to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;:warning: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; MUST be used in lieu of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;. :warning:&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines a universal registry smart contract where any address (contract or regular account) can register which interface it supports and which smart contract is responsible for its implementation.&lt;&#x2F;p&gt;
&lt;p&gt;This standard keeps backward compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines a registry where smart contracts and regular accounts can publish which functionality they implement---either directly or through a proxy contract.&lt;&#x2F;p&gt;
&lt;p&gt;Anyone can query this registry to ask if a specific address implements a given interface and which smart contract handles its implementation.&lt;&#x2F;p&gt;
&lt;p&gt;This registry MAY be deployed on any chain and shares the same address on all chains.&lt;&#x2F;p&gt;
&lt;p&gt;Interfaces with zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;) as the last 28 bytes are considered &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interfaces,
and this registry SHALL forward the call to the contract to see if it implements the interface.&lt;&#x2F;p&gt;
&lt;p&gt;This contract also acts as an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache to reduce gas consumption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There have been different approaches to define pseudo-introspection in Ethereum.
The first is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; which has the limitation that it cannot be used by regular accounts.
The second attempt is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;672&quot;&gt;ERC-672&lt;&#x2F;a&gt; which uses reverse &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt;. Using reverse &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt; has two issues.
First, it is unnecessarily complicated, and second, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt; is still a centralized contract controlled by a multisig.
This multisig theoretically would be able to modify the system.&lt;&#x2F;p&gt;
&lt;p&gt;This standard is much simpler than &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;672&quot;&gt;ERC-672&lt;&#x2F;a&gt;, and it is &lt;em&gt;fully&lt;&#x2F;em&gt; decentralized.&lt;&#x2F;p&gt;
&lt;p&gt;This standard also provides a &lt;em&gt;unique&lt;&#x2F;em&gt; address for all chains.
Thus solving the problem of resolving the correct registry address for different chains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;erc-1820-registry-smart-contract&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; Registry Smart Contract&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is an exact copy of the code of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC1820&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;ERC1820Registry.sol&quot;&gt;ERC1820 registry smart contract&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC1820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * This standard defines a universal registry smart contract where any address (contract or regular account) can&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * register which interface it supports and which smart contract is responsible for its implementation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Written in 2019 by Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * this software to the public domain worldwide. This software is distributed without any warranty.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &amp;lt;http:&#x2F;&#x2F;creativecommons.org&#x2F;publicdomain&#x2F;zero&#x2F;1.0&#x2F;&amp;gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ███████╗██████╗  ██████╗ ██╗ █████╗ ██████╗  ██████╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔════╝██╔══██╗██╔════╝███║██╔══██╗╚════██╗██╔═████╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    █████╗  ██████╔╝██║     ╚██║╚█████╔╝ █████╔╝██║██╔██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══╝  ██╔══██╗██║      ██║██╔══██╗██╔═══╝ ████╔╝██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ███████╗██║  ██║╚██████╗ ██║╚█████╔╝███████╗╚██████╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚══════╝ ╚═════╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗   ██╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   ██████╔╝ ╚████╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══██╗  ╚██╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ██║  ██║   ██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.5.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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IV is value needed to have a vanity address starting with &amp;#39;0x1820&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IV: 53759&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface a contract MUST implement if it is the implementer of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; some (other) interface for any address other than itself.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates whether the contract implements the interface &amp;#39;interfaceHash&amp;#39; for the address &amp;#39;addr&amp;#39; or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ERC1820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only if the contract implements &amp;#39;interfaceHash&amp;#39; for the address &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC1820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @author&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This contract is the official implementation of the ERC1820 Registry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For more details, see https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1820Registry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 Invalid ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; INVALID_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xffffffff&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256(&amp;#39;supportsInterface(bytes4)&amp;#39;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Magic value which is returned if a contract implements an interface on behalf of some other address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; ERC1820_ACCEPT_MAGIC &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC1820_ACCEPT_MAGIC&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; mapping from addresses and interface hashes to their implementers.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; mapping from addresses to their manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; managers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; flag for each address and erc165 interface to indicate if it is cached.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; erc165Cached&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates a contract is the &amp;#39;implementer&amp;#39; of &amp;#39;interfaceHash&amp;#39; for &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; implementer&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates &amp;#39;newManager&amp;#39; is the address of the new manager for &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ManagerChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newManager&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address being queried for the implementer of an interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; E.g., &amp;#39;web3.utils.keccak256(&amp;quot;ERC777TokensRecipient&amp;quot;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the contract which implements the interface &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or &amp;#39;0&amp;#39; if &amp;#39;_addr&amp;#39; did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            bytes4&lt;&#x2F;span&gt;&lt;span&gt; erc165InterfaceHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; erc165InterfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the contract which implements a specific interface for an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the manager defined for that address can set it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which to set the interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; E.g., &amp;#39;web3.utils.keccak256(&amp;quot;ERC777TokensRecipient&amp;quot;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Contract address implementing &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not the manager&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Must not be an ERC165 hash&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_implementer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; _implementer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;                ERC1820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_implementer&lt;&#x2F;span&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;span class=&quot;z-entity z-name&quot;&gt;canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; ERC1820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;Does not implement the interface&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _implementer&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets &amp;#39;_newManager&amp;#39; as manager for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new manager will be able to call &amp;#39;setInterfaceImplementer&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the new manager for &amp;#39;addr&amp;#39;. (Pass &amp;#39;0x0&amp;#39; to reset the manager to &amp;#39;_addr&amp;#39;.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not the manager&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _newManager &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ManagerChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _newManager&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the manager of an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which to return the manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the manager for a given address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; By default the manager of an address is the same address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Name of the interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; --- ERC165 Related Functions --- &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; --- Developed in collaboration with William Entriken. --- &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateERC165Cache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; _contract &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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&gt;        erc165Cached&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  If the result is not cached a direct lookup on the contract address is performed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  &amp;#39;updateERC165Cache&amp;#39; with the contract address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;erc165Cached&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _contract&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; INVALID_ID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if &amp;#39;_interfaceHash&amp;#39; is an ERC165 interface (ending with 28 zeroes), false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _interfaceHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make a call on a contract without throwing if the function does not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-storage z-type&quot;&gt;        internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt; erc165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&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 class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x40&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find empty storage location using &amp;quot;free memory pointer&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; erc165ID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place signature at beginning of empty storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;            mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x04&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place first argument directly next to signature&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;            success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; staticcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                30000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 30k gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; To addr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are stored at location x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                0x24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are 36 (4 + 32) bytes long&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Store output over input (saves space)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                0x20&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                           &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Outputs are 32 bytes long&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&gt;            result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Load the result&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;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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;deployment-transaction&quot;&gt;Deployment Transaction&lt;&#x2F;h3&gt;
&lt;p&gt;Below is the raw transaction which MUST be used to deploy the smart contract on any chain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf90a388085174876e800830c35008080b909e5608060405234801561001057600080fd5b506109c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063a41e7d5111610078578063a41e7d51146101d4578063aabbb8ca1461020a578063b705676514610236578063f712f3e814610280576100a5565b806329965a1d146100aa5780633d584063146100e25780635df8122f1461012457806365ba36c114610152575b600080fd5b6100e0600480360360608110156100c057600080fd5b50600160a060020a038135811691602081013591604090910135166102b6565b005b610108600480360360208110156100f857600080fd5b5035600160a060020a0316610570565b60408051600160a060020a039092168252519081900360200190f35b6100e06004803603604081101561013a57600080fd5b50600160a060020a03813581169160200135166105bc565b6101c26004803603602081101561016857600080fd5b81019060208101813564010000000081111561018357600080fd5b82018360208201111561019557600080fd5b803590602001918460018302840111640100000000831117156101b757600080fd5b5090925090506106b3565b60408051918252519081900360200190f35b6100e0600480360360408110156101ea57600080fd5b508035600160a060020a03169060200135600160e060020a0319166106ee565b6101086004803603604081101561022057600080fd5b50600160a060020a038135169060200135610778565b61026c6004803603604081101561024c57600080fd5b508035600160a060020a03169060200135600160e060020a0319166107ef565b604080519115158252519081900360200190f35b61026c6004803603604081101561029657600080fd5b508035600160a060020a03169060200135600160e060020a0319166108aa565b6000600160a060020a038416156102cd57836102cf565b335b9050336102db82610570565b600160a060020a031614610339576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b6103428361092a565b15610397576040805160e560020a62461bcd02815260206004820152601a60248201527f4d757374206e6f7420626520616e204552433136352068617368000000000000604482015290519081900360640190fd5b600160a060020a038216158015906103b85750600160a060020a0382163314155b156104ff5760405160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040516020818303038152906040528051906020012082600160a060020a031663249cb3fa85846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b15801561047e57600080fd5b505afa158015610492573d6000803e3d6000fd5b505050506040513d60208110156104a857600080fd5b5051146104ff576040805160e560020a62461bcd02815260206004820181905260248201527f446f6573206e6f7420696d706c656d656e742074686520696e74657266616365604482015290519081900360640190fd5b600160a060020a03818116600081815260208181526040808320888452909152808220805473ffffffffffffffffffffffffffffffffffffffff19169487169485179055518692917f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db15391a450505050565b600160a060020a03818116600090815260016020526040812054909116151561059a5750806105b7565b50600160a060020a03808216600090815260016020526040902054165b919050565b336105c683610570565b600160a060020a031614610624576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b81600160a060020a031681600160a060020a0316146106435780610646565b60005b600160a060020a03838116600081815260016020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169585169590951790945592519184169290917f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a43509190a35050565b600082826040516020018083838082843780830192505050925050506040516020818303038152906040528051906020012090505b92915050565b6106f882826107ef565b610703576000610705565b815b600160a060020a03928316600081815260208181526040808320600160e060020a031996909616808452958252808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181209281529190925220805460ff19166001179055565b600080600160a060020a038416156107905783610792565b335b905061079d8361092a565b156107c357826107ad82826108aa565b6107b85760006107ba565b815b925050506106e8565b600160a060020a0390811660009081526020818152604080832086845290915290205416905092915050565b6000808061081d857f01ffc9a70000000000000000000000000000000000000000000000000000000061094c565b909250905081158061082d575080155b1561083d576000925050506106e8565b61084f85600160e060020a031961094c565b909250905081158061086057508015155b15610870576000925050506106e8565b61087a858561094c565b909250905060018214801561088f5750806001145b1561089f576001925050506106e8565b506000949350505050565b600160a060020a0382166000908152600260209081526040808320600160e060020a03198516845290915281205460ff1615156108f2576108eb83836107ef565b90506106e8565b50600160a060020a03808316600081815260208181526040808320600160e060020a0319871684529091529020549091161492915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6040517f01ffc9a7000000000000000000000000000000000000000000000000000000008082526004820183905260009182919060208160248189617530fa90519096909550935050505056fea165627a7a72305820377f4a2d4301ede9949f163f319021a6e9c687c292a5e2b2c4734c126b524e6c00291ba01820182018201820182018201820182018201820182018201820182018201820a01820182018201820182018201820182018201820182018201820182018201820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The strings of &lt;code&gt;1820&lt;&#x2F;code&gt;&#x27;s at the end of the transaction are the &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; of the signature.
From this deterministic pattern (generated by a human), anyone can deduce that no one knows the private key for the deployment account.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deployment-method&quot;&gt;Deployment Method&lt;&#x2F;h3&gt;
&lt;p&gt;This contract is going to be deployed using the keyless deployment method---also known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Arachnid&#x2F;&quot;&gt;Nick&lt;&#x2F;a&gt;&#x27;s method---which relies on a single-use address.
(See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@weka&#x2F;how-to-send-ether-to-11-440-people-187e332566b7&quot;&gt;Nick&#x27;s article&lt;&#x2F;a&gt; for more details). This method works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Generate a transaction which deploys the contract from a new random account.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;This transaction MUST NOT use &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; in order to work on any chain.&lt;&#x2F;li&gt;
&lt;li&gt;This transaction MUST have a relatively high gas price to be deployed on any chain. In this case, it is going to be 100 Gwei.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;Set the &lt;code&gt;v&lt;&#x2F;code&gt;, &lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; of the transaction signature to the following values:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;v: 27,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;r: 0x1820182018201820182018201820182018201820182018201820182018201820&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s: 0x1820182018201820182018201820182018201820182018201820182018201820&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; values---made of a repeating pattern of &lt;code&gt;1820&lt;&#x2F;code&gt;&#x27;s---are predictable &quot;random numbers&quot; generated deterministically by a human.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We recover the sender of this transaction, i.e., the single-use deployment account.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thus we obtain an account that can broadcast that transaction, but we also have the warranty that nobody knows the private key of that account.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Send exactly 0.08 ether to this single-use deployment account.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Broadcast the deployment transaction.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This operation can be done on any chain, guaranteeing that the contract address is always the same and nobody can use that address with a different contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;single-use-registry-deployment-account&quot;&gt;Single-use Registry Deployment Account&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xa990077c3205cbDf861e17Fa532eeB069cE9fF96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This account is generated by reverse engineering it from its signature for the transaction.
This way no one knows the private key, but it is known that it is the valid signer of the deployment transaction.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To deploy the registry, 0.08 ether MUST be sent to this account &lt;em&gt;first&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;registry-contract-address&quot;&gt;Registry Contract Address&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&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;The contract has the address above for every chain on which it is deployed.&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;Raw metadata of &lt;code&gt;.&#x2F;contracts&#x2F;ERC1820Registry.sol&lt;&#x2F;code&gt;&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;compiler&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0.5.3+commit.10d17f24&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;language&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;output&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;            {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;setManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;updateERC165Cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementsERC165Interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;anonymous&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;anonymous&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ManagerChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;devdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;author&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;methods&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getInterfaceImplementer(address,bytes32)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address being queried for the implementer of an interface. (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Keccak256 hash of the name of the interface as a string. E.g., &amp;#39;web3.utils.keccak256(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC777TokensRecipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The address of the contract which implements the interface &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39; or &amp;#39;0&amp;#39; if &amp;#39;_addr&amp;#39; did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getManager(address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address for which to return the manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the manager for a given address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165Interface(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;True if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165InterfaceNoCache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;True if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;interfaceHash(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name of the interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setInterfaceImplementer(address,bytes32,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address for which to set the interface. (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract address implementing &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Keccak256 hash of the name of the interface as a string. E.g., &amp;#39;web3.utils.keccak256(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC777TokensRecipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setManager(address,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the new manager for &amp;#39;addr&amp;#39;. (Pass &amp;#39;0x0&amp;#39; to reset the manager to &amp;#39;_addr&amp;#39;.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;updateERC165Cache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC1820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;userdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;methods&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getInterfaceImplementer(address,bytes32)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getManager(address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Get the manager of an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165InterfaceNoCache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;interfaceHash(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setInterfaceImplementer(address,bytes32,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sets the contract which implements a specific interface for an address. Only the manager defined for that address can set it. (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setManager(address,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sets &amp;#39;_newManager&amp;#39; as manager for &amp;#39;_addr&amp;#39;. The new manager will be able to call &amp;#39;setInterfaceImplementer&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;              &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;updateERC165Cache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;This contract is the official implementation of the ERC1820 Registry.For more details, see https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1820&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;compilationTarget&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;.&#x2F;contracts&#x2F;ERC1820Registry.sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC1820Registry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;evmVersion&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;byzantium&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;libraries&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;optimizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;runs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;remappings&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sources&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;.&#x2F;contracts&#x2F;ERC1820Registry.sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;* ERC1820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * This standard defines a universal registry smart contract where any address (contract or regular account) can&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * register which interface it supports and which smart contract is responsible for its implementation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * Written in 2019 by Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * this software to the public domain worldwide. This software is distributed without any warranty.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * &amp;lt;http:&#x2F;&#x2F;creativecommons.org&#x2F;publicdomain&#x2F;zero&#x2F;1.0&#x2F;&amp;gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ███████╗██████╗  ██████╗ ██╗ █████╗ ██████╗  ██████╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔════╝██╔══██╗██╔════╝███║██╔══██╗╚════██╗██╔═████╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    █████╗  ██████╔╝██║     ╚██║╚█████╔╝ █████╔╝██║██╔██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══╝  ██╔══██╗██║      ██║██╔══██╗██╔═══╝ ████╔╝██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ███████╗██║  ██║╚██████╗ ██║╚█████╔╝███████╗╚██████╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚══════╝ ╚═════╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗   ██╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   ██████╔╝ ╚████╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══██╗  ╚██╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ██║  ██║   ██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pragma solidity 0.5.3;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F; IV is value needed to have a vanity address starting with &amp;#39;0x1820&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F; IV: 53759&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @dev The interface a contract MUST implement if it is the implementer of&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; some (other) interface for any address other than itself.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interface ERC1820ImplementerInterface {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates whether the contract implements the interface &amp;#39;interfaceHash&amp;#39; for the address &amp;#39;addr&amp;#39; or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param interfaceHash keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param addr Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return ERC1820_ACCEPT_MAGIC only if the contract implements &amp;#39;interfaceHash&amp;#39; for the address &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @title ERC1820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @author Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @notice This contract is the official implementation of the ERC1820 Registry.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @notice For more details, see https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1820&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;contract ERC1820Registry {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice ERC165 Invalid ID.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes4 constant internal INVALID_ID = 0xffffffff;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256(&amp;#39;supportsInterface(bytes4)&amp;#39;))`).&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes4 constant internal ERC165ID = 0x01ffc9a7;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Magic value which is returned if a contract implements an interface on behalf of some other address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes32 constant internal ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;));&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice mapping from addresses and interface hashes to their implementers.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping(address =&amp;gt; mapping(bytes32 =&amp;gt; address)) internal interfaces;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice mapping from addresses to their manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping(address =&amp;gt; address) internal managers;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice flag for each address and erc165 interface to indicate if it is cached.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping(address =&amp;gt; mapping(bytes4 =&amp;gt; bool)) internal erc165Cached;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates a contract is the &amp;#39;implementer&amp;#39; of &amp;#39;interfaceHash&amp;#39; for &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates &amp;#39;newManager&amp;#39; is the address of the new manager for &amp;#39;addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    event ManagerChanged(address indexed addr, address indexed newManager);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address being queried for the implementer of an interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash Keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; E.g., &amp;#39;web3.utils.keccak256(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC777TokensRecipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return The address of the contract which implements the interface &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; or &amp;#39;0&amp;#39; if &amp;#39;_addr&amp;#39; did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        address addr = _addr == address(0) ? msg.sender : _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (isERC165Interface(_interfaceHash)) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            bytes4 erc165InterfaceHash = bytes4(_interfaceHash);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return implementsERC165Interface(addr, erc165InterfaceHash) ? addr : address(0);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return interfaces[addr][_interfaceHash];&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Sets the contract which implements a specific interface for an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; Only the manager defined for that address can set it.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address for which to set the interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; (If &amp;#39;_addr&amp;#39; is the zero address then &amp;#39;msg.sender&amp;#39; is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash Keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; E.g., &amp;#39;web3.utils.keccak256(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC777TokensRecipient&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&amp;#39; for the &amp;#39;ERC777TokensRecipient&amp;#39; interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _implementer Contract address implementing &amp;#39;_interfaceHash&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        address addr = _addr == address(0) ? msg.sender : _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(getManager(addr) == msg.sender, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not the manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(!isERC165Interface(_interfaceHash), &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Must not be an ERC165 hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (_implementer != address(0) &amp;amp;&amp;amp; _implementer != msg.sender) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            require(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                ERC1820ImplementerInterface(_implementer)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    .canImplementInterfaceForAddress(_interfaceHash, addr) == ERC1820_ACCEPT_MAGIC,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;                \&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Does not implement the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            );&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        interfaces[addr][_interfaceHash] = _implementer;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        emit InterfaceImplementerSet(addr, _interfaceHash, _implementer);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Sets &amp;#39;_newManager&amp;#39; as manager for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; The new manager will be able to call &amp;#39;setInterfaceImplementer&amp;#39; for &amp;#39;_addr&amp;#39;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _newManager Address of the new manager for &amp;#39;addr&amp;#39;. (Pass &amp;#39;0x0&amp;#39; to reset the manager to &amp;#39;_addr&amp;#39;.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function setManager(address _addr, address _newManager) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(getManager(_addr) == msg.sender, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not the manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        managers[_addr] = _newManager == _addr ? address(0) : _newManager;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        emit ManagerChanged(_addr, _newManager);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Get the manager of an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address for which to return the manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return Address of the manager for a given address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function getManager(address _addr) public view returns(address) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        &#x2F;&#x2F; By default the manager of an address is the same address&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (managers[_addr] == address(0)) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        } else {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return managers[_addr];&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceName Name of the interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return The keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function interfaceHash(string calldata _interfaceName) external pure returns(bytes32) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return keccak256(abi.encodePacked(_interfaceName));&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;* --- ERC165 Related Functions --- *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;* --- Developed in collaboration with William Entriken. --- *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function updateERC165Cache(address _contract, bytes4 _interfaceId) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        interfaces[_contract][_interfaceId] = implementsERC165InterfaceNoCache(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            _contract, _interfaceId) ? _contract : address(0);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        erc165Cached[_contract][_interfaceId] = true;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether a contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;  If the result is not cached a direct lookup on the contract address is performed.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;  &amp;#39;updateERC165Cache&amp;#39; with the contract address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return True if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (!erc165Cached[_contract][_interfaceId]) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return implementsERC165InterfaceNoCache(_contract, _interfaceId);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return interfaces[_contract][_interfaceId] == _contract;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return True if &amp;#39;_contract&amp;#39; implements &amp;#39;_interfaceId&amp;#39;, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        uint256 success;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        uint256 result;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, ERC165ID);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 0 || result == 0) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, INVALID_ID);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 0 || result != 0) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, _interfaceId);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 1 &amp;amp;&amp;amp; result == 1) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return true;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash The hash to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return True if &amp;#39;_interfaceHash&amp;#39; is an ERC165 interface (ending with 28 zeroes), false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return _interfaceHash &amp;amp; 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @dev Make a call on a contract without throwing if the function does not exist.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function noThrowCall(address _contract, bytes4 _interfaceId)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        internal view returns (uint256 success, uint256 result)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        bytes4 erc165ID = ERC165ID;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        assembly {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            let x := mload(0x40)               &#x2F;&#x2F; Find empty storage location using &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;free memory pointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            mstore(x, erc165ID)                &#x2F;&#x2F; Place signature at beginning of empty storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            mstore(add(x, 0x04), _interfaceId) &#x2F;&#x2F; Place first argument directly next to signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            success := staticcall(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                30000,                         &#x2F;&#x2F; 30k gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                _contract,                     &#x2F;&#x2F; To addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                x,                             &#x2F;&#x2F; Inputs are stored at location x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                0x24,                          &#x2F;&#x2F; Inputs are 36 (4 + 32) bytes long&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                x,                             &#x2F;&#x2F; Store output over input (saves space)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                0x20                           &#x2F;&#x2F; Outputs are 32 bytes long&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            )&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            result := mload(x)                 &#x2F;&#x2F; Load the result&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x64025ecebddb6e126a5075c1fd6c01de2840492668e2909cef7157040a9d1945&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&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;&#x2F;details&gt;
&lt;h3 id=&quot;interface-name&quot;&gt;Interface Name&lt;&#x2F;h3&gt;
&lt;p&gt;Any interface name is hashed using &lt;code&gt;keccak256&lt;&#x2F;code&gt; and sent to &lt;code&gt;getInterfaceImplementer()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the interface is part of a standard, it is best practice to explicitly state the interface name and link to this published &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; such that other people don&#x27;t have to come here to look up these rules.&lt;&#x2F;p&gt;
&lt;p&gt;For convenience, the registry provides a function to compute the hash on-chain:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&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;Compute the keccak256 hash of an interface given its name.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;65ba36c1&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceName&lt;&#x2F;code&gt;: Name of the interface.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; The &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of an interface name.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;approved-ercs&quot;&gt;&lt;strong&gt;Approved ERCs&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;If the interface is part of an approved ERC, it MUST be named &lt;code&gt;ERC###XXXXX&lt;&#x2F;code&gt; where &lt;code&gt;###&lt;&#x2F;code&gt; is the number of the ERC and XXXXX should be the name of the interface in CamelCase.
The meaning of this interface SHOULD be defined in the specified ERC.&lt;&#x2F;p&gt;
&lt;p&gt;Examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC20Token&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777Token&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777TokensSender&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777TokensRecipient&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc-165-compatible-interfaces&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Compatible Interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, including the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;#erc165-cache&quot;&gt;ERC165 Cache&lt;&#x2F;a&gt;, has been designed and developed with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fulldecent&quot;&gt;William Entriken&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Any interface where the last 28 bytes are zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;) SHALL be considered an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Lookup&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anyone can explicitly check if a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface using the registry by calling one of the two functions below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Checks whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not.&lt;&#x2F;p&gt;
&lt;p&gt;If the result is not cached a direct lookup on the contract address is performed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt; with the contract address.
(See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;#erc165-cache&quot;&gt;ERC165 Cache&lt;&#x2F;a&gt; for more details.)&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;f712f3e8&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;_contract&lt;&#x2F;code&gt; implements &lt;code&gt;_interfaceId&lt;&#x2F;code&gt;, &lt;code&gt;false&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Checks whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not without using nor updating the cache.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;b7056765&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;_contract&lt;&#x2F;code&gt; implements &lt;code&gt;_interfaceId&lt;&#x2F;code&gt;, false otherwise.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Cache&lt;&#x2F;strong&gt; &lt;a id=&quot;erc165-cache&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not can be cached manually to save gas.&lt;&#x2F;p&gt;
&lt;p&gt;If a contract dynamically changes its interface and relies on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; registry, the cache MUST be updated manually---there is no automatic cache invalidation or cache update.
Ideally the contract SHOULD automatically update the cache when changing its interface.
However anyone MAY update the cache on the contract&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;The cache update MUST be done using the &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateERC165Cache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;a41e7d51&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract for which to update the cache.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface for which to update the cache.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;private-user-defined-interfaces&quot;&gt;&lt;strong&gt;Private User-defined Interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;This scheme is extensible.
You MAY make up your own interface name and raise awareness to get other people to implement it and then check for those implementations.
Have fun but please, you MUST not conflict with the reserved designations above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;set-an-interface-for-an-address&quot;&gt;Set An Interface For An Address&lt;&#x2F;h3&gt;
&lt;p&gt;For any address to set a contract as the interface implementation, it must call the following function of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; registry:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sets the contract which implements a specific interface for an address.&lt;&#x2F;p&gt;
&lt;p&gt;Only the &lt;code&gt;manager&lt;&#x2F;code&gt; defined for that address can set it.
(Each address is the manager for itself, see the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;#manager&quot;&gt;manager&lt;&#x2F;a&gt; section for more details.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If  &lt;code&gt;_addr&lt;&#x2F;code&gt; and &lt;code&gt;_implementer&lt;&#x2F;code&gt; are two different addresses, then:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;_implementer&lt;&#x2F;code&gt; MUST implement the &lt;code&gt;ERC1820ImplementerInterface&lt;&#x2F;code&gt; (detailed below).&lt;&#x2F;li&gt;
&lt;li&gt;Calling &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; on &lt;code&gt;_implementer&lt;&#x2F;code&gt; with the given &lt;code&gt;_addr&lt;&#x2F;code&gt; and  &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; MUST return the &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt; value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; MUST NOT be an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface---it MUST NOT end with 28 zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_addr&lt;&#x2F;code&gt; MAY be &lt;code&gt;0&lt;&#x2F;code&gt;, then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed.
This default value simplifies interactions via multisigs where the data of the transaction to sign is constant regardless of the address of the multisig instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;29965a1d&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address for which to set the interface. (If &lt;code&gt;_addr&lt;&#x2F;code&gt; is the zero address then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed.)&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;: Keccak256 hash of the name of the interface as a string, for example &lt;code&gt;web3.utils.keccak256(&#x27;ERC777TokensRecipient&#x27;)&lt;&#x2F;code&gt; for the ERC777TokensRecipient interface.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_implementer&lt;&#x2F;code&gt;: Contract implementing &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;get-an-implementation-of-an-interface-for-an-address&quot;&gt;Get An Implementation Of An Interface For An Address&lt;&#x2F;h3&gt;
&lt;p&gt;Anyone MAY query the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; Registry to obtain the address of a contract implementing an interface on behalf of some address using the &lt;code&gt;getInterfaceImplementer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&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;Query if an address implements an interface and through which contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If the last 28 bytes of the &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; are zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;), then the first 4 bytes are considered an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface and the registry SHALL forward the call to the contract at &lt;code&gt;_addr&lt;&#x2F;code&gt; to see if it implements the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface (the first 4 bytes of &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;).
The registry SHALL also cache &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; queries to reduce gas consumption. Anyone MAY call the &lt;code&gt;erc165UpdateCache&lt;&#x2F;code&gt; function to update whether a contract implements an interface or not.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_addr&lt;&#x2F;code&gt; MAY be &lt;code&gt;0&lt;&#x2F;code&gt;, then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed.
This default value is consistent with the behavior of the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function and simplifies interactions via multisigs where the data of the transaction to sign is constant regardless of the address of the multisig instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;aabbb8ca&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address being queried for the implementer of an interface. (If &lt;code&gt;_addr&lt;&#x2F;code&gt; is the zero address then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed.)&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;: keccak256 hash of the name of the interface as a string. E.g. &lt;code&gt;web3.utils.keccak256(&#x27;ERC777Token&#x27;)&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; The address of the contract which implements the interface &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt; or &lt;code&gt;0&lt;&#x2F;code&gt; if &lt;code&gt;_addr&lt;&#x2F;code&gt; did not register an implementer for this interface.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;interface-implementation-erc1820implementerinterface&quot;&gt;Interface Implementation (&lt;code&gt;ERC1820ImplementerInterface&lt;&#x2F;code&gt;)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates whether the contract implements the interface `interfaceHash` for the address `addr` or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ERC1820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only if the contract implements `interfaceHash` for the address `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any contract being registered as the implementation of an interface for a given address MUST implement said interface.
In addition if it implements an interface on behalf of a different address, the contract MUST implement the &lt;code&gt;ERC1820ImplementerInterface&lt;&#x2F;code&gt; shown above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&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;Indicates whether a contract implements an interface (&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;) for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;If a contract implements the interface (&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;) for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;), it MUST return &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt; when called with the &lt;code&gt;addr&lt;&#x2F;code&gt; and the &lt;code&gt;interfaceHash&lt;&#x2F;code&gt;.
If it does not implement the &lt;code&gt;interfaceHash&lt;&#x2F;code&gt; for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;), it MUST NOT return &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;f0083250&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;: Hash of the interface which is implemented&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;addr&lt;&#x2F;code&gt;: Address for which the interface is implemented&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt; only if the contract implements &lt;code&gt;ìnterfaceHash&lt;&#x2F;code&gt; for the address &lt;code&gt;addr&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The special value &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt; is defined as the &lt;code&gt;keccka256&lt;&#x2F;code&gt; hash of the string &lt;code&gt;&quot;ERC1820_ACCEPT_MAGIC&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; ERC1820_ACCEPT_MAGIC &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC1820_ACCEPT_MAGIC&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&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&gt;
&lt;p&gt;The reason to return &lt;code&gt;ERC1820_ACCEPT_MAGIC&lt;&#x2F;code&gt; instead of a boolean is to prevent cases where a contract fails to implement the &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; but implements a fallback function which does not throw. In this case, since &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; does not exist, the fallback function is called instead, executed without throwing and returns &lt;code&gt;1&lt;&#x2F;code&gt;. Thus making it appear as if &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; returned &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;manager&quot;&gt;Manager&lt;&#x2F;h3&gt;
&lt;p&gt;The manager of an address (regular account or a contract) is the only entity allowed to register implementations of interfaces for the address.
By default, any address is its own manager.&lt;&#x2F;p&gt;
&lt;p&gt;The manager can transfer its role to another address by calling &lt;code&gt;setManager&lt;&#x2F;code&gt; on the registry contract with the address for which to transfer the manager and the address of the new manager.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;setManager&lt;&#x2F;code&gt; Function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sets &lt;code&gt;_newManager&lt;&#x2F;code&gt; as manager for &lt;code&gt;_addr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The new manager will be able to call &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;_newManager&lt;&#x2F;code&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;, the manager is reset to &lt;code&gt;_addr&lt;&#x2F;code&gt; itself as the manager.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;5df8122f&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address for which to set the new manager.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_newManager&lt;&#x2F;code&gt;: The address of the new manager for &lt;code&gt;_addr&lt;&#x2F;code&gt;. (Pass &lt;code&gt;0x0&lt;&#x2F;code&gt; to reset the manager to &lt;code&gt;_addr&lt;&#x2F;code&gt;.)&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;getManager&lt;&#x2F;code&gt; Function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&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;Get the manager of an address.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;3d584063&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address for which to return the manager.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Address of the manager for a given address.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standards offers a way for any type of address (externally owned and contracts) to implement an interface and potentially delegate the implementation of the interface to a proxy contract.
This delegation to a proxy contract is necessary for externally owned accounts and useful to avoid redeploying existing contracts such as multisigs and DAOs.&lt;&#x2F;p&gt;
&lt;p&gt;The registry can also act as a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache in order to save gas when looking up if a contract implements a specific &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface.
This cache is intentionally kept simple, without automatic cache update or invalidation.
Anyone can easily and safely update the cache for any interface and any contract by calling the &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The registry is deployed using a keyless deployment method relying on a single-use deployment address to ensure no one controls the registry, thereby ensuring trust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backward-compatibility&quot;&gt;Backward Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, as both methods MAY be implemented without conflicting with each other.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Please check the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC1820&quot;&gt;0xjac&#x2F;ERC1820&lt;&#x2F;a&gt; repository for the full test suite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation is available in the repo: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC1820&quot;&gt;0xjac&#x2F;ERC1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Petersburg&quot;</title>
        <published>2019-01-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Afri Schoedon</name><uri>https://github.com/5chdn</uri>
	</author>
	
	<author>
		<name>Marius van der Wijden</name><uri>https://github.com/MariusVanDerWijden</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1716/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/1716/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:1716"
            label="EIP-1716" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1716/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This meta-EIP specifies the changes included in the Ethereum hardfork that removes &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;&quot;&gt;EIP-1283&lt;&#x2F;a&gt; from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1013&#x2F;&quot;&gt;Constantinople&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Petersburg&lt;&#x2F;li&gt;
&lt;li&gt;Aliases: St. Petersfork, Peter&#x27;s Fork, Constantinople Fix&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 7_280_000&lt;&#x2F;code&gt; on the Ethereum Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 4_939_394&lt;&#x2F;code&gt; on the Ropsten testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 10_255_201&lt;&#x2F;code&gt; on the Kovan testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 4_321_234&lt;&#x2F;code&gt; on the Rinkeby testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 0&lt;&#x2F;code&gt; on the Görli testnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Removed EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;&quot;&gt;EIP-1283&lt;&#x2F;a&gt;: Net gas metering for SSTORE without dirty maps&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If &lt;code&gt;Petersburg&lt;&#x2F;code&gt; and &lt;code&gt;Constantinople&lt;&#x2F;code&gt; are applied at the same block, &lt;code&gt;Petersburg&lt;&#x2F;code&gt; takes precedence: with the net effect of EIP-1283 being &lt;em&gt;disabled&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;Petersburg&lt;&#x2F;code&gt; is defined with an earlier block number than &lt;code&gt;Constantinople&lt;&#x2F;code&gt;, then there is &lt;em&gt;no immediate effect&lt;&#x2F;em&gt; from the &lt;code&gt;Petersburg&lt;&#x2F;code&gt; fork. However, when &lt;code&gt;Constantinople&lt;&#x2F;code&gt; is later activated, EIP-1283 should be &lt;em&gt;disabled&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;The list above includes the EIPs that had to be removed from Constantinople due to a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;chainsecurity&#x2F;constantinople-enables-new-reentrancy-attack-ace4088297d9&quot;&gt;potential reentrancy attack vector&lt;&#x2F;a&gt;. Removing this was agreed upon at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;issues&#x2F;70&quot;&gt;All-Core-Devs call #53 in January 2019&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2019&#x2F;02&#x2F;22&#x2F;ethereum-constantinople-st-petersburg-upgrade-announcement&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Istanbul&quot;</title>
        <published>2019-01-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Afri Schoedon</name><uri>https://github.com/5chdn</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1679/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/hardfork-meta-istanbul-discussion/3207" />
        

        <id>https://wg-eips.ritovision.com/1679/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:1679"
            label="EIP-1679" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1679/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This meta-EIP specifies the changes included in the Ethereum hardfork named Istanbul.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Istanbul&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;activation&quot;&gt;Activation&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 9,069,000&lt;&#x2F;code&gt; on the Ethereum Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 6,485,846&lt;&#x2F;code&gt; on the Ropsten testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 14,111,141&lt;&#x2F;code&gt; on the Kovan testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 5,435,345&lt;&#x2F;code&gt; on the Rinkeby testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 1,561,651&lt;&#x2F;code&gt; on the Görli testnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;included-eips&quot;&gt;Included EIPs&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;152&#x2F;&quot;&gt;EIP-152&lt;&#x2F;a&gt;: Add Blake2 compression function &lt;code&gt;F&lt;&#x2F;code&gt; precompile&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1108&#x2F;&quot;&gt;EIP-1108&lt;&#x2F;a&gt;: Reduce alt_bn128 precompile gas costs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1344&#x2F;&quot;&gt;EIP-1344&lt;&#x2F;a&gt;: Add ChainID opcode&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1884&#x2F;&quot;&gt;EIP-1884&lt;&#x2F;a&gt;: Repricing for trie-size-dependent opcodes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2028&#x2F;&quot;&gt;EIP-2028&lt;&#x2F;a&gt;: Calldata gas cost reduction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt;: Rebalance net-metered SSTORE gas cost with consideration of SLOAD gas cost change&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Included EIPs were finalized in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2068.md&quot;&gt;All Core Devs Call #68&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;medium.com&#x2F;ethereum-cat-herders&#x2F;istanbul-testnets-are-coming-53973bcea7df&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Payable Token</title>
        <published>2018-08-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Vittorio Minacori</name><uri>https://github.com/vittominacori</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1363/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/eips/issues/1363" />
        

        <id>https://wg-eips.ritovision.com/1363/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:1363"
            label="ERC-1363" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1363/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Defines a token interface for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens that supports executing recipient code after &lt;code&gt;transfer&lt;&#x2F;code&gt; or &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, or spender code after &lt;code&gt;approve&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Standard functions a token contract and contracts working with tokens can implement to make a token Payable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;transferAndCall&lt;&#x2F;code&gt; and &lt;code&gt;transferFromAndCall&lt;&#x2F;code&gt; will call an &lt;code&gt;onTransferReceived&lt;&#x2F;code&gt; on a &lt;code&gt;ERC1363Receiver&lt;&#x2F;code&gt; contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;approveAndCall&lt;&#x2F;code&gt; will call an &lt;code&gt;onApprovalReceived&lt;&#x2F;code&gt; on a &lt;code&gt;ERC1363Spender&lt;&#x2F;code&gt; contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There is no way to execute code after a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; transfer or approval (i.e. making a payment), so to make an action it is required to send another transaction and pay GAS twice.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal wants to make token payments easier and working without the use of any other listener. It allows to make a callback after a transfer or approval in a single transaction.&lt;&#x2F;p&gt;
&lt;p&gt;There are many proposed uses of Ethereum smart contracts that can accept &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; payments.&lt;&#x2F;p&gt;
&lt;p&gt;Examples could be&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;to create a token payable crowdsale&lt;&#x2F;li&gt;
&lt;li&gt;selling services for tokens&lt;&#x2F;li&gt;
&lt;li&gt;paying invoices&lt;&#x2F;li&gt;
&lt;li&gt;making subscriptions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For these reasons it was named as &lt;strong&gt;&quot;Payable Token&quot;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway you can use it for specific utilities or for any other purposes who require the execution of a callback after a transfer or approval received.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal has been inspired by the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; &lt;code&gt;onERC721Received&lt;&#x2F;code&gt; and &lt;code&gt;ERC721TokenReceiver&lt;&#x2F;code&gt; behaviours.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Implementing contracts &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1363&#x2F;&quot;&gt;ERC-1363&lt;&#x2F;a&gt; interface as well as the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interfaces.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1363&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC20, ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0xb0202a11.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * 0xb0202a11 ===&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;transferAndCall(address,uint256)&amp;#39;)) ^&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;transferAndCall(address,uint256,bytes)&amp;#39;)) ^&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;transferFromAndCall(address,address,uint256)&amp;#39;)) ^&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;transferFromAndCall(address,address,uint256,bytes)&amp;#39;)) ^&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;approveAndCall(address,uint256)&amp;#39;)) ^&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *   bytes4(keccak256(&amp;#39;approveAndCall(address,uint256,bytes)&amp;#39;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to transfer to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to transfer to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes Additional data with no specified format, sent in call to `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer tokens from one address to another and then call `onTransferReceived` on receiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to send tokens from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to transfer to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFromAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer tokens from one address to another and then call `onTransferReceived` on receiver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to send tokens from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which you want to transfer to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes Additional data with no specified format, sent in call to `to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFromAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approve the passed address to spend the specified amount of tokens on behalf of msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * and then call `onApprovalReceived` on spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which will spend the funds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be spent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approveAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Approve the passed address to spend the specified amount of tokens on behalf of msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * and then call `onApprovalReceived` on spender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which will spend the funds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be spent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes Additional data with no specified format, sent in call to `spender`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approveAndCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;  event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A contract that wants to accept token payments via &lt;code&gt;transferAndCall&lt;&#x2F;code&gt; or &lt;code&gt;transferFromAndCall&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC1363Receiver interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for any contract that wants to support `transferAndCall` or `transferFromAndCall`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  from ERC1363 token contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1363Receiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x88a7ca5c.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * 0x88a7ca5c === bytes4(keccak256(&amp;quot;onTransferReceived(address,address,uint256,bytes)&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the receipt of ERC1363 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Any ERC1363 smart contract calls this function on the recipient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * transfer. Return of other than the magic value MUST result in the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * transaction being reverted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the token contract address is always the message sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which called `transferAndCall` or `transferFromAndCall` function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which are token transferred from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `bytes4(keccak256(&amp;quot;onTransferReceived(address,address,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *  unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onTransferReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A contract that wants to accept token payments via &lt;code&gt;approveAndCall&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC1363Spender interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface for any contract that wants to support `approveAndCall`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *  from ERC1363 token contracts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1363Spender&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x7b04a2d0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * 0x7b04a2d0 === bytes4(keccak256(&amp;quot;onApprovalReceived(address,uint256,bytes)&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&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 class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the approval of ERC1363 tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Any ERC1363 smart contract calls this function on the recipient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * after an `approve`. This function MAY throw to revert and reject the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * approval. Return of other than the magic value MUST result in the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * transaction being reverted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the token contract address is always the message sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address The address which called `approveAndCall` function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uint256 The amount of tokens to be spent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `bytes4(keccak256(&amp;quot;onApprovalReceived(address,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *  unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onApprovalReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The choice to use &lt;code&gt;transferAndCall&lt;&#x2F;code&gt;, &lt;code&gt;transferFromAndCall&lt;&#x2F;code&gt; and &lt;code&gt;approveAndCall&lt;&#x2F;code&gt; derives from the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; naming. They want to highlight that they have the same behaviours of &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;transferFrom&lt;&#x2F;code&gt; and &lt;code&gt;approve&lt;&#x2F;code&gt; with the addition of a callback on receiver or spender.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal has been inspired also by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;223&quot;&gt;ERC-223&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;677&quot;&gt;ERC-677&lt;&#x2F;a&gt; but it uses the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; approach, so it doesn&#x27;t override the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; methods and defines the interfaces IDs to be implemented maintaining the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; backwards compatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;approveAndCall&lt;&#x2F;code&gt; and &lt;code&gt;transferFromAndCall&lt;&#x2F;code&gt; methods can be affected by the same issue of the standard &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;Changing an allowance with the &lt;code&gt;approveAndCall&lt;&#x2F;code&gt; methods brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering.&lt;&#x2F;p&gt;
&lt;p&gt;One possible solution to mitigate this race condition is to first reduce the spender&#x27;s allowance to 0 and set the desired value afterwards (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;20#issuecomment-263524729&quot;&gt;EIP-20#issuecomment-263524729&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ChainID opcode</title>
        <published>2018-08-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Richard Meissner</name><uri>https://github.com/rmeissner</uri>
	</author>
	
	<author>
		<name>Bryant Eisenbach</name><uri>https://github.com/fubuloubu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1344/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/add-chain-id-opcode-for-replay-protection-when-handling-signed-messages-in-contracts/1131" />
        

        <id>https://wg-eips.ritovision.com/1344/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1344"
            label="EIP-1344" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1344/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP adds an opcode that returns the current chain&#x27;s EIP-155 unique identifier.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; proposes to use the chain ID to prevent replay attacks between different chains. It would be a great benefit to have the same possibility inside smart contracts when handling signatures, especially for Layer 2 signature schemes using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Adds a new opcode &lt;code&gt;CHAINID&lt;&#x2F;code&gt; at 0x46, which uses 0 stack arguments. It pushes the current chain ID onto the stack. Chain ID is a 256-bit value. The operation costs &lt;code&gt;G_base&lt;&#x2F;code&gt; to execute.&lt;&#x2F;p&gt;
&lt;p&gt;The value of the current chain ID is obtained from the chain ID configuration, which should match the EIP-155 unique identifier a client will accept from incoming transactions. Please note that per EIP-155, it is not &lt;em&gt;required&lt;&#x2F;em&gt; that a transaction have an EIP-155 unique identifier, but in that scenario this opcode will still return the configured chain ID and not a default.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The current approach proposed by EIP-712 is to specify the chain ID at compile time. Using this approach will result in problems after a hardfork, as well as human error that may lead to loss of funds or replay attacks on signed messages.
By adding the proposed opcode it will be possible to access the current chain ID and validate signatures based on that.&lt;&#x2F;p&gt;
&lt;p&gt;Currently, there is no specification for how chain ID is set for a particular network, relying on choices made manually by the client implementers and the chain community. There is a potential scenario where, during a &quot;contentious split&quot; over a divisive issue, a community using a particular value of chain ID will make a decision to split into two such chains. When this scenario occurs, it will be unsafe to maintain chain ID to the same value on both chains, as chain ID is used for replay protection for in-protocol transactions (per EIP-155), as well as for L2 and &quot;meta-transaction&quot; use cases (per EIP-712 as enabled by this proposal). There are two potential resolutions in this scenario under the current process: 1) one chain decides to modify their value of chain ID (while the other keeps it), or 2) both chains decide to modify their value of chain ID.&lt;&#x2F;p&gt;
&lt;p&gt;In order to mitigate this situation, users of the proposed &lt;code&gt;CHAINID&lt;&#x2F;code&gt; opcode &lt;strong&gt;must&lt;&#x2F;strong&gt; ensure that their application can handle a potential update to the value of chain ID during their usage of their application in case this does occur, if required for the continued use of the application. A Trustless Oracle that logs the timestamp when a change is made to chain ID can be implemented either as an application-level feature inside the application contract system, or referenced as a globally standard contract. Failure to provide a mitigation for this scenario could lead to a sudden loss of legitimacy of previously signed off-chain messages, which could be an issue during settlement periods and other longer-term verification events for these types of messages. Not all applications of this opcode may need mitigations to handle this scenario, but developers should provide reasoning on a case-by-case basis.&lt;&#x2F;p&gt;
&lt;p&gt;One example of a scenario where it would not make sense to leverage a global oracle is with the Plasma L2 paradigm. In the Plasma paradigm, an operator or group of operators submit blocks from the L2 network to the base chain (in this case Ethereum) summarizing transactions that have occurred on that chain. The submission of these blocks may not perfectly align with major events on the mainchain, such as a split causing an update of chain ID, which may cause a significant insecurity in the protocol if chain ID is utilized in signing messages. If the operators are not allowed to control the update of chain ID they will not be able to perfectly synchronize the update with their block submissions, and certain past transactions may be rejected because they do not align with the update. This is one example of the unintended consequences of trying to specify too much of the behavior of chain ID during a contentious split, and why having a simple opcode for access is most optimal, versus a more complicated precompile or contract.&lt;&#x2F;p&gt;
&lt;p&gt;This proposed opcode would be the simplest possible way to implement this functionality, and allows developers the flexibility to implement their own global or local handling of chain ID changes, if required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is fully backwards compatible with all chains which implement EIP-155 chain ID domain separator for transaction signing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;This was previously suggested as part of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;901&quot;&gt;EIP-901&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test Cases added to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;pull&#x2F;627&quot;&gt;ethereum&#x2F;tests&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation for the Trinity Python client is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;py-evm&#x2F;pull&#x2F;1803&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An example implementation of a trustless chain ID oracle was implemented &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fubuloubu&#x2F;chain-id-oracle&#x2F;blob&#x2F;master&#x2F;ChainIdOracle.vy&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>WalletConnect URI Format</title>
        <published>2018-08-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>ligi</name><uri>https://github.com/ligi</uri>
	</author>
	
	<author>
		<name>Pedro Gomes</name><uri>https://github.com/pedrouid</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1328/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/wallet-connect-eip/850" />
        

        <id>https://wg-eips.ritovision.com/1328/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1328"
            label="ERC-1328" />
        

        
        

        
        <summary type="html">Define URI format for initiating connections between applications and wallets</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1328/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines how the data to connect some application and a wallet can be encoded with a URI. This URI can then be shown either as a QR code or as a link.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;syntax&quot;&gt;Syntax&lt;&#x2F;h3&gt;
&lt;p&gt;WalletConnect request URI with the following parameters:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request       = &amp;quot;wc&amp;quot; &amp;quot;:&amp;quot; topic [ &amp;quot;@&amp;quot; version ][ &amp;quot;?&amp;quot; parameters ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;topic         = STRING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;version       = 1*DIGIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parameters    = parameter *( &amp;quot;&amp;amp;&amp;quot; parameter )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parameter     = key &amp;quot;=&amp;quot; value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key           = STRING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;value         = STRING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;semantics&quot;&gt;Semantics&lt;&#x2F;h3&gt;
&lt;p&gt;Required parameters are dependent on the WalletConnect protocol version:&lt;&#x2F;p&gt;
&lt;p&gt;For WalletConnect v1.0 protocol (&lt;code&gt;version&lt;&#x2F;code&gt;=&lt;code&gt;1&lt;&#x2F;code&gt;) the parameters are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;key&lt;&#x2F;code&gt; - symmetric key used for encryption&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bridge&lt;&#x2F;code&gt; - url of the bridge server for relaying messages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For WalletConnect v2.0 protocol (&lt;code&gt;version&lt;&#x2F;code&gt;=&lt;code&gt;2&lt;&#x2F;code&gt;) the parameters are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symKey&lt;&#x2F;code&gt; - symmetric key used for encrypting messages over relay&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;methods&lt;&#x2F;code&gt; - jsonrpc methods supported for pairing topic&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;relay-protocol&lt;&#x2F;code&gt; - transport protocol for relaying messages&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;relay-data&lt;&#x2F;code&gt; - (optional) transport data for relaying messages&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;expiryTimestamp&lt;&#x2F;code&gt; - (optional) unix epoch in seconds when pairing expires&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# 1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wc:8a5e5bdc-a0e4-4702-ba63-8f1a5655744f@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&amp;amp;key=41791102999c339c844880b23950704cc43aa840f3739e365323cda4dfa89e7a&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;# 2.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wc:7f6e504bfad60b485450578e05678ed3e8e8c4751d3c6160be17160d63ec90f9@2?relay-protocol=irn&amp;amp;symKey=587d5484ce2a2a6ee3ba1962fdd7e8588e06200c46823bd18fbd67def96ad303&amp;amp;methods=[wc_sessionPropose],[wc_authRequest,wc_authBatchRequest]&amp;quot;&amp;amp;expiryTimestamp=1705934757&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal moves away from the JSON format used in the alpha version of the WalletConnect protocol because it suffered from very inefficient parsing of the intent of the QR code, thereby making it easier to create better QR code parsers APIs for wallets to implement. Also by using a URI instead of JSON inside the QR-Code the Android Intent system can be leveraged.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Versioning is required as part of the syntax for this URI specification to allow the WalletConnect protocol to evolve and allow backwards-compatibility whenever a new version is introduced.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;URIs should be shared between user devices or applications and no sensitive data is shared within the URI that could compromise the communication or would allow control of the user&#x27;s private keys.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>wallet_watchAsset RPC Method</title>
        <published>2018-08-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Dan Finlay</name><uri>https://github.com/danfinlay</uri>
	</author>
	
	<author>
		<name>Esteban Mino</name><uri>https://github.com/estebanmino</uri>
	</author>
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/747/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-747-eth-watchtoken/1048" />
        

        <id>https://wg-eips.ritovision.com/747/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:747"
            label="EIP-747" />
        

        
        

        
        <summary type="html">Adds a new RPC method that allows websites to prompt users to watch an asset</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/747/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP standardizes a new wallet-scoped RPC method, &lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt;, to allow a client to suggest a token for the user&#x27;s wallet to track.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Today, one of the major uses of Ethereum wallets is to track users&#x27; assets.
Without this EIP, each wallet either needs to pre-load a list of approved assets, or users must manually add assets to their wallet.
In the first case, wallets are burdened with both the security of managing this list, as well as the bandwidth of mass polling for known assets on their wallet.
In the second case, the user experience is terrible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;p&gt;A new RPC method, &lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; is added. &lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; requests that a specified asset be listed to the user&#x27;s wallet. It MUST immediately (i.e. before prompting the user) return &lt;code&gt;true&lt;&#x2F;code&gt; if the request was valid, or error if it was not. The meaning of &quot;listed to the user&#x27;s wallet&quot; is dependent on the wallet implementation. A successful call to &lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; MUST indicate that the wallet recognized the request and that it contained no issues, but doesn&#x27;t indicate whether the user was prompted or whether the asset was actually added to the wallet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-watchasset-parameters&quot;&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; Parameters&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; method takes a single parameter, a &lt;code&gt;WatchAssetParameters&lt;&#x2F;code&gt; object, which is defined as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WatchAssetParameters&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The asset&amp;#39;s interface, e.g. &amp;#39;ERC1046&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; any&lt;&#x2F;span&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 &lt;code&gt;type&lt;&#x2F;code&gt; string SHOULD be the commonly accepted name of the interface implemented by the asset&#x27;s contract, e.g. &lt;code&gt;ERC1046&lt;&#x2F;code&gt;. Defining the global identifiers for different asset types is beyond the scope of this EIP.&lt;&#x2F;p&gt;
&lt;p&gt;This interface SHOULD be extended or modified depending on the asset &lt;code&gt;type&lt;&#x2F;code&gt;. These changes MUST be specified in separate EIPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet-watchasset-returns&quot;&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; Returns&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; immediately (i.e. without waiting for user interaction) returns the boolean value &lt;code&gt;true&lt;&#x2F;code&gt; to indicate that the request was recognized (regardless of whether the user was prompted), or errors if the request is invalid. An error might occur in the following circumstances (not comprehensive):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The asset type is unrecognized&#x2F;unsupported&lt;&#x2F;li&gt;
&lt;li&gt;The asset was blocked due to an allowlist or denylist (this makes the request &#x27;invalid&#x27; since the root cause requires developer action)&lt;&#x2F;li&gt;
&lt;li&gt;Downloading the image failed to load
&lt;ul&gt;
&lt;li&gt;The wallet didn&#x27;t load some of the metadata required to display the asset, in order to protect against a potential SSRF attack&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;erc1046-type&quot;&gt;&lt;code&gt;ERC1046&lt;&#x2F;code&gt; type&lt;&#x2F;h3&gt;
&lt;p&gt;The format of the options field is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1046WatchAssetOptions&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hexadecimal address of the token contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The chain ID of the asset. If empty, defaults to the current chain ID.&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&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;&lt;code&gt;address&lt;&#x2F;code&gt; is required, and the other fields are optional. &lt;code&gt;address&lt;&#x2F;code&gt; MUST be the &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed checksummed hexadecimal address of the token contract. &lt;code&gt;chainId&lt;&#x2F;code&gt; MUST be the chain ID to which the asset belongs.&lt;&#x2F;p&gt;
&lt;p&gt;If the checksum fails, the request MUST be considered invalid.&lt;&#x2F;p&gt;
&lt;p&gt;If the wallet does not recognize the &lt;code&gt;chainId&lt;&#x2F;code&gt;, or the &lt;code&gt;chainId&lt;&#x2F;code&gt; is blank and the wallet does not have a concept of &quot;active&quot; chain, the call MUST fail.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; MUST fetch the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1046&#x2F;&quot;&gt;ERC-1046&lt;&#x2F;a&gt; &lt;code&gt;tokenURI&lt;&#x2F;code&gt; and check the &lt;code&gt;interop&lt;&#x2F;code&gt; field to determine the type of the token. If the parsing fails, or the type is unknown, the RPC call MUST error.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; SHOULD check the &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; fields, and the contract &lt;code&gt;address&lt;&#x2F;code&gt; and &lt;code&gt;chainId&lt;&#x2F;code&gt; against a list of well-known tokens. If the name and&#x2F;or symbol are similar to ones on the list but the &lt;code&gt;chainId&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;address&lt;&#x2F;code&gt; don&#x27;t match, a warning SHOULD be presented to the user.&lt;&#x2F;p&gt;
&lt;p&gt;The wallet SHOULD whitelist and&#x2F;or blacklist specific ports and schemes to avoid SSRF attacks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;legacy-erc20-type&quot;&gt;Legacy &lt;code&gt;ERC20&lt;&#x2F;code&gt; type&lt;&#x2F;h3&gt;
&lt;p&gt;The format of the options field is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20WatchAssetOptions&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hexadecimal address of the token contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The chain ID of the asset. If empty, defaults to the current chain ID.&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&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;&lt;code&gt;address&lt;&#x2F;code&gt; is required, and the other fields are optional. &lt;code&gt;address&lt;&#x2F;code&gt; MUST be the &lt;code&gt;0x&lt;&#x2F;code&gt;-prefixed checksummed hexadecimal address of the token contract. &lt;code&gt;chainId&lt;&#x2F;code&gt; MUST be the chain ID to which the asset belongs.&lt;&#x2F;p&gt;
&lt;p&gt;If the checksum fails, the request MUST be considered invalid.&lt;&#x2F;p&gt;
&lt;p&gt;If the wallet does not recognize the &lt;code&gt;chainId&lt;&#x2F;code&gt;, or the &lt;code&gt;chainId&lt;&#x2F;code&gt; is blank and the wallet does not have a concept of &quot;active&quot; chain, the call MUST fail.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;wallet_watchAsset&lt;&#x2F;code&gt; SHOULD check the &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; fields, and the contract &lt;code&gt;address&lt;&#x2F;code&gt; and &lt;code&gt;chainId&lt;&#x2F;code&gt; against a list of well-known tokens. If the name and&#x2F;or symbol are similar to ones on the list but the &lt;code&gt;chainId&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;address&lt;&#x2F;code&gt; don&#x27;t match, a warning SHOULD be presented to the user.&lt;&#x2F;p&gt;
&lt;p&gt;If possible, it is RECOMMENDED to instead use the &lt;code&gt;ERC1046&lt;&#x2F;code&gt; type, which supports images and custom metadata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Displaying a user&#x27;s assets is a basic feature that every modern DApp user expects. Most wallets currently either manage their own asset lists, which they store client-side, or they query a centralized API for balances, which reduces decentralization and allows correlating account holders with IP addresses. Additionally, refreshing&#x2F;polling an asset list from the network can be costly, especially on bandwidth-constrained devices. Also, maintaining an asset list becomes a political act, provoking harassment and inducing pressure to list obscure assets.&lt;&#x2F;p&gt;
&lt;p&gt;Automatically listing assets makes assets into a sort of spam mail: Users suddenly see new assets that they don&#x27;t care about in their wallet. This can be used to send unsolicited information, or even to conduct phishing scams. This phenomenon is already common with airdropped tokens, a major cause of network congestion, because spamming people with new tokens has, so far, been rewarded with increased user attention.&lt;&#x2F;p&gt;
&lt;p&gt;When a user is manually adding an asset, they had likely previously learned about it from a website. At that moment, there was a natural alignment of interests, where both parties wanted the user to track the token. This is a natural point to introduce an API to easily allow these parties to collaborate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;server-side-request-forgery&quot;&gt;Server-Side Request Forgery&lt;&#x2F;h3&gt;
&lt;p&gt;Wallets should be careful about making arbitrary requests to URLs. As such, it is recommended for wallets to sanitize the URI by whitelisting specific schemes and ports. A vulnerable wallet could be tricked into, for example, modifying data on a locally-hosted redis database.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;validation&quot;&gt;Validation&lt;&#x2F;h3&gt;
&lt;p&gt;Wallets should warn users if the symbol or name matches or is similar to another token, to avoid phishing scams.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fingerprinting&quot;&gt;Fingerprinting&lt;&#x2F;h3&gt;
&lt;p&gt;To avoid fingerprinting based on wallet behavior and&#x2F;or listed assets, the RPC call must return as soon as the user is prompted or an error occurs, without waiting for the user to accept or deny the prompt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Net gas metering for SSTORE without dirty maps</title>
        <published>2018-08-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Wei Tang</name><uri>https://github.com/sorpaas</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1283/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/sorpaas/EIPs/issues/1" />
        

        <id>https://wg-eips.ritovision.com/1283/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:1283"
            label="EIP-1283" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1283/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes net gas metering changes for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; opcode, enabling
new usages for contract storage, and reducing excessive gas costs
where it doesn&#x27;t match how most implementations work.&lt;&#x2F;p&gt;
&lt;p&gt;This acts as an alternative for EIP-1087, where it tries to be
friendlier to implementations that use different optimization
strategies for storage change caches.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP proposes a way for gas metering on SSTORE (as an alternative
for EIP-1087 and EIP-1153), using information that is more universally
available to most implementations, and requires as little change in
implementation structures as possible.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Storage slot&#x27;s original value&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Storage slot&#x27;s current value&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Usages that benefits from this EIP&#x27;s gas reduction scheme includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Subsequent storage write operations within the same call frame. This
includes reentry locks, same-contract multi-send, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Exchange storage information between sub call frame and parent call
frame, where this information does not need to be persistent outside
of a transaction. This includes sub-frame error codes and message
passing, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Definitions of terms are as below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Storage slot&#x27;s original value&lt;&#x2F;em&gt;: This is the value of the storage if
a reversion happens on the &lt;em&gt;current transaction&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Storage slot&#x27;s current value&lt;&#x2F;em&gt;: This is the value of the storage
before SSTORE operation happens.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Storage slot&#x27;s new value&lt;&#x2F;em&gt;: This is the value of the storage after
SSTORE operation happens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Replace &lt;code&gt;SSTORE&lt;&#x2F;code&gt; opcode gas cost calculation (including refunds) with
the following logic:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; equals &lt;em&gt;new value&lt;&#x2F;em&gt; (this is a no-op), 200 gas is
deducted.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; does not equal &lt;em&gt;new value&lt;&#x2F;em&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; equals &lt;em&gt;current value&lt;&#x2F;em&gt; (this storage slot has
not been changed by the current execution context)
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, 20000 gas is deducted.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, 5000 gas is deducted. If &lt;em&gt;new value&lt;&#x2F;em&gt; is 0, add 15000
gas to refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; does not equal &lt;em&gt;current value&lt;&#x2F;em&gt; (this storage
slot is dirty), 200 gas is deducted. Apply both of the following
clauses.
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is not 0
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;current value&lt;&#x2F;em&gt; is 0 (also means that &lt;em&gt;new value&lt;&#x2F;em&gt; is not
0), remove 15000 gas from refund counter. We can prove that
refund counter will never go below 0.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;new value&lt;&#x2F;em&gt; is 0 (also means that &lt;em&gt;current value&lt;&#x2F;em&gt; is not
0), add 15000 gas to refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; equals &lt;em&gt;new value&lt;&#x2F;em&gt; (this storage slot is
reset)
&lt;ul&gt;
&lt;li&gt;If &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, add 19800 gas to refund counter.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise, add 4800 gas to refund counter.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Refund counter works as before -- it is limited to half of the gas
consumed. On a transaction level, refund counter will never go below
zero. However, there are some important notes depending on the
implementation details:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If an implementation uses &quot;transaction level&quot; refund counter (refund
is checkpointed at each call frame), then the refund counter
continues to be unsigned.&lt;&#x2F;li&gt;
&lt;li&gt;If an implementation uses &quot;execution-frame level&quot; refund counter
(a new refund counter is created at each call frame, and then merged
back to parent when the call frame finishes), then the refund
counter needs to be changed to signed -- at internal calls, a child
refund can go below zero.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;&#x2F;h2&gt;
&lt;p&gt;The new gas cost scheme for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; is divided into three different
types:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No-op&lt;&#x2F;strong&gt;: the virtual machine does not need to do anything. This is
the case if &lt;em&gt;current value&lt;&#x2F;em&gt; equals &lt;em&gt;new value&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Fresh&lt;&#x2F;strong&gt;: this storage slot has not been changed, or has been reset
to its original value. This is the case if &lt;em&gt;current value&lt;&#x2F;em&gt; does not
equal &lt;em&gt;new value&lt;&#x2F;em&gt;, and &lt;em&gt;original value&lt;&#x2F;em&gt; equals &lt;em&gt;current value&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Dirty&lt;&#x2F;strong&gt;: this storage slot has already been changed. This is the
case if &lt;em&gt;current value&lt;&#x2F;em&gt; does not equal &lt;em&gt;new value&lt;&#x2F;em&gt;, and &lt;em&gt;original
value&lt;&#x2F;em&gt; does not equal &lt;em&gt;current value&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can see that the above three types cover all possible variations of
&lt;em&gt;original value&lt;&#x2F;em&gt;, &lt;em&gt;current value&lt;&#x2F;em&gt;, and &lt;em&gt;new value&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No-op&lt;&#x2F;strong&gt; is a trivial operation. Below we only consider cases for
&lt;strong&gt;Fresh&lt;&#x2F;strong&gt; and &lt;strong&gt;Dirty&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;All initial (not-&lt;strong&gt;No-op&lt;&#x2F;strong&gt;) &lt;code&gt;SSTORE&lt;&#x2F;code&gt; on a particular storage slot starts
with &lt;strong&gt;Fresh&lt;&#x2F;strong&gt;. After that, it will become &lt;strong&gt;Dirty&lt;&#x2F;strong&gt; if the value has
been changed. When going from &lt;strong&gt;Fresh&lt;&#x2F;strong&gt; to &lt;strong&gt;Dirty&lt;&#x2F;strong&gt;, we charge the
gas cost the same as current scheme. A &lt;strong&gt;Dirty&lt;&#x2F;strong&gt; storage slot can be
reset back to &lt;strong&gt;Fresh&lt;&#x2F;strong&gt; via a &lt;code&gt;SSTORE&lt;&#x2F;code&gt; opcode. This will trigger a
refund.&lt;&#x2F;p&gt;
&lt;p&gt;When a storage slot remains at &lt;strong&gt;Dirty&lt;&#x2F;strong&gt;, we charge 200 gas. In this
case, we would also need to keep track of &lt;code&gt;R_SCLEAR&lt;&#x2F;code&gt; refunds -- if we
already issued the refund but it no longer applies (&lt;em&gt;current value&lt;&#x2F;em&gt; is
0), then removes this refund from the refund counter. If we didn&#x27;t
issue the refund but it applies now (&lt;em&gt;new value&lt;&#x2F;em&gt; is 0), then adds this
refund to the refund counter. It is not possible where a refund is not
issued but we remove the refund in the above case, because all storage
slot starts with &lt;strong&gt;Fresh&lt;&#x2F;strong&gt; state.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;state-transition&quot;&gt;State Transition&lt;&#x2F;h3&gt;
&lt;p&gt;Below is a graph (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;pull&#x2F;1283#issuecomment-410229053&quot;&gt;by
@Arachnid&lt;&#x2F;a&gt;)
showing possible state transition of gas costs. We ignore &lt;strong&gt;No-op&lt;&#x2F;strong&gt;
state because that is trivial:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;.&#x2F;assets&#x2F;state.png&quot; alt=&quot;State Transition&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below is table version of the above diagram. Vertical shows the &lt;em&gt;new
value&lt;&#x2F;em&gt; being set, and horizontal shows the state of &lt;em&gt;original value&lt;&#x2F;em&gt;
and &lt;em&gt;current value&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is 0:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;A (&lt;code&gt;current=orig=0&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;th&gt;B (&lt;code&gt;current!=orig&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;~0&lt;&#x2F;td&gt;&lt;td&gt;B; 20k gas&lt;&#x2F;td&gt;&lt;td&gt;B; 200 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;A; 200 gas&lt;&#x2F;td&gt;&lt;td&gt;A; 200 gas, 19.8k refund&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is not 0:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;X (&lt;code&gt;current=orig!=0&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;th&gt;Y (&lt;code&gt;current!=orig&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;th&gt;Z (&lt;code&gt;current=0&lt;&#x2F;code&gt;)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;orig&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X; 200 gas&lt;&#x2F;td&gt;&lt;td&gt;X; 200 gas, 4.8k refund&lt;&#x2F;td&gt;&lt;td&gt;X; 200 gas, -10.2k refund&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;~orig, ~0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Y; 5k gas&lt;&#x2F;td&gt;&lt;td&gt;Y; 200 gas&lt;&#x2F;td&gt;&lt;td&gt;Y; 200 gas, -15k refund&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;Z; 5k gas, 15k refund&lt;&#x2F;td&gt;&lt;td&gt;Z; 200 gas, 15k refund&lt;&#x2F;td&gt;&lt;td&gt;Z; 200 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP mostly achieves what a transient storage tries to do
(EIP-1087 and EIP-1153), but without the complexity of introducing the
concept of &quot;dirty maps&quot;, or an extra storage struct.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We don&#x27;t suffer from the optimization limitation of
EIP-1087. EIP-1087 requires keeping a dirty map for storage changes,
and implicitly makes the assumption that a transaction&#x27;s storage
changes are committed to the storage trie at the end of a
transaction. This works well for some implementations, but not for
others. After EIP-658, an efficient storage cache implementation
would probably use an in-memory trie (without RLP encoding&#x2F;decoding)
or other immutable data structures to keep track of storage changes,
and only commit changes at the end of a block. For them, it is
possible to know a storage&#x27;s original value and current value, but
it is not possible to iterate over all storage changes without
incurring additional memory or processing costs.&lt;&#x2F;li&gt;
&lt;li&gt;It never costs more gas compared with the current scheme.&lt;&#x2F;li&gt;
&lt;li&gt;It covers all usages for a transient storage. Clients that are easy
to implement EIP-1087 will also be easy to implement this
specification. Some other clients might require a little bit extra
refactoring on this. Nonetheless, no extra memory or processing cost
is needed on runtime.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Regarding &lt;code&gt;SSTORE&lt;&#x2F;code&gt; gas cost and refunds, see Appendix for proofs of
properties that this EIP satisfies.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For &lt;em&gt;absolute gas used&lt;&#x2F;em&gt; (that is, actual &lt;em&gt;gas used&lt;&#x2F;em&gt; minus &lt;em&gt;refund&lt;&#x2F;em&gt;),
this EIP is equivalent to EIP-1087 for all cases.&lt;&#x2F;li&gt;
&lt;li&gt;For one particular case, where a storage slot is changed, reset to
its original value, and then changed again, EIP-1283 would move more
gases to refund counter compared with EIP-1087.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Examine examples provided in EIP-1087&#x27;s Motivation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If a contract with empty storage sets slot 0 to 1, then back to 0,
it will be charged &lt;code&gt;20000 + 200 - 19800 = 400&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;A contract with empty storage that increments slot 0 5 times will be
charged &lt;code&gt;20000 + 5 * 200 = 21000&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;A balance transfer from account A to account B followed by a
transfer from B to C, with all accounts having nonzero starting and
ending balances, it will cost &lt;code&gt;5000 * 3 + 200 - 4800 = 10400&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP requires a hard fork to implement. No gas cost increase is
anticipated, and many contracts will see gas reduction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Below we provide 17 test cases. 15 of them covering consecutive two
&lt;code&gt;SSTORE&lt;&#x2F;code&gt; operations are based on work &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;issues&#x2F;483&quot;&gt;by
@chfast&lt;&#x2F;a&gt;. Two additional
cases with three &lt;code&gt;SSTORE&lt;&#x2F;code&gt; operations is used to test the case when a
slot is reset and then set again.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Used Gas&lt;&#x2F;th&gt;&lt;th&gt;Refund&lt;&#x2F;th&gt;&lt;th&gt;Original&lt;&#x2F;th&gt;&lt;th&gt;1st&lt;&#x2F;th&gt;&lt;th&gt;2nd&lt;&#x2F;th&gt;&lt;th&gt;3rd&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;412&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20212&lt;&#x2F;td&gt;&lt;td&gt;19800&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;4800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60006000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556003600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;4800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60026000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;15000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556002600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;5212&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x60016000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;412&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600160005560006000556001600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;40218&lt;&#x2F;td&gt;&lt;td&gt;19800&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x600060005560016000556000600055&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;10218&lt;&#x2F;td&gt;&lt;td&gt;19800&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;appendix-proof&quot;&gt;Appendix: Proof&lt;&#x2F;h2&gt;
&lt;p&gt;Because the &lt;em&gt;storage slot&#x27;s original value&lt;&#x2F;em&gt; is defined as the value
when a reversion happens on the &lt;em&gt;current transaction&lt;&#x2F;em&gt;, it&#x27;s easy to
see that call frames won&#x27;t interfere SSTORE gas calculation. So
although the below proof is discussed without call frames, it applies
to all situations with call frames. We will discuss the case
separately for &lt;em&gt;original value&lt;&#x2F;em&gt; being zero and not zero, and use
&lt;em&gt;induction&lt;&#x2F;em&gt; to prove some properties of SSTORE gas cost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Final value&lt;&#x2F;em&gt; is the value of a particular storage slot at the end of
a transaction. &lt;em&gt;Absolute gas used&lt;&#x2F;em&gt; is the absolute value of &lt;em&gt;gas used&lt;&#x2F;em&gt;
minus &lt;em&gt;refund&lt;&#x2F;em&gt;. We use &lt;code&gt;N&lt;&#x2F;code&gt; to represent the total number of SSTORE
operations on a storage slot. For states discussed below, refer to
&lt;em&gt;State Transition&lt;&#x2F;em&gt; in &lt;em&gt;Explanation&lt;&#x2F;em&gt; section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;original-value-being-zero&quot;&gt;Original Value Being Zero&lt;&#x2F;h3&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is 0, we want to prove that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Case I&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up still being 0, we want to charge &lt;code&gt;200 * N&lt;&#x2F;code&gt; gases, because no disk write is needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case II&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being a non-zero value, we want to
charge &lt;code&gt;20000 + 200 * (N-1)&lt;&#x2F;code&gt; gas, because it requires writing this
slot to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;base-case&quot;&gt;Base Case&lt;&#x2F;h4&gt;
&lt;p&gt;We always start at state A. The first SSTORE can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Go to state A: 200 gas is deducted. We satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt; because
&lt;code&gt;200 * N == 200 * 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state B: 20000 gas is deducted. We satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt; because
&lt;code&gt;20000 + 200 * (N-1) == 20000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;inductive-step&quot;&gt;Inductive Step&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;From A to A. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
gas cost is &lt;code&gt;200 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From A to B. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
gas cost is &lt;code&gt;20000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From B to B. The previous gas cost is &lt;code&gt;20000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 + 20000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy
&lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From B to A. The previous gas cost is &lt;code&gt;20000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 - 19800 + 20000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy
&lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;original-value-not-being-zero&quot;&gt;Original Value Not Being Zero&lt;&#x2F;h3&gt;
&lt;p&gt;When &lt;em&gt;original value&lt;&#x2F;em&gt; is not 0, we want to prove that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Case I&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up unchanged, we want to
charge &lt;code&gt;200 * N&lt;&#x2F;code&gt; gases, because no disk write is needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case II&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being zero, we want to
charge &lt;code&gt;5000 - 15000 + 200 * (N-1)&lt;&#x2F;code&gt; gas. Note that &lt;code&gt;15000&lt;&#x2F;code&gt; is the
refund in actual definition.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Case III&lt;&#x2F;strong&gt;: If the &lt;em&gt;final value&lt;&#x2F;em&gt; ends up being a changed non-zero
value, we want to charge &lt;code&gt;5000 + 200 * (N-1)&lt;&#x2F;code&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;base-case-1&quot;&gt;Base Case&lt;&#x2F;h4&gt;
&lt;p&gt;We always start at state X. The first SSTORE can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Go to state X: 200 gas is deducted. We satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt; because
&lt;code&gt;200 * N == 200 * 1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state Y: 5000 gas is deducted. We satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt; because
&lt;code&gt;5000 + 200 * (N-1) == 5000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to state Z: The absolute gas used is &lt;code&gt;5000 - 15000&lt;&#x2F;code&gt; where 15000
is the refund. We satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt; because &lt;code&gt;5000 - 15000 + 200 * (N-1) == 5000 - 15000 + 200 * 0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;inductive-step-1&quot;&gt;Inductive Step&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;From X to X. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current gas
cost is &lt;code&gt;200 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From X to Y. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current gas
cost is &lt;code&gt;5000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From X to Z. The previous gas cost is &lt;code&gt;200 * (N-1)&lt;&#x2F;code&gt;. The current
absolute gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-1)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case
II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to X. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
absolute current gas cost is &lt;code&gt;200 - 4800 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It
satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to Y. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current gas cost is &lt;code&gt;200 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case
III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Y to Z. The previous gas cost is &lt;code&gt;5000 + 200 * (N-2)&lt;&#x2F;code&gt;. The
current absolute gas cost is &lt;code&gt;200 - 15000 + 5000 + 200 * (N-2)&lt;&#x2F;code&gt;. It
satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to X. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 10200 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case I&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to Y. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 15000 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case III&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;From Z to Z. The previous gas cost is &lt;code&gt;5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. The current absolute gas cost is &lt;code&gt;200 + 5000 - 15000 + 200 * (N-2)&lt;&#x2F;code&gt;. It satisfy &lt;em&gt;Case II&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Standard Signature Validation Method for Contracts</title>
        <published>2018-07-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Francisco Giordano</name><uri>https://github.com/frangio</uri>
	</author>
	
	<author>
		<name>Matt Condon</name><uri>https://github.com/shrugs</uri>
	</author>
	
	<author>
		<name>Philippe Castonguay</name><uri>https://github.com/PhABC</uri>
	</author>
	
	<author>
		<name>Amir Bandeali</name><uri>https://github.com/abandeali1</uri>
	</author>
	
	<author>
		<name>Jorge Izquierdo</name><uri>https://github.com/izqui</uri>
	</author>
	
	<author>
		<name>Bertrand Masius</name><uri>https://github.com/catageek</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1271/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/1271" />
        

        <id>https://wg-eips.ritovision.com/1271/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:1271"
            label="ERC-1271" />
        

        
        

        
        <summary type="html">Standard way to verify a signature when the account is a smart contract</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1271/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Externally Owned Accounts (EOA) can sign messages with their associated private keys, but currently contracts cannot. We propose a standard way for any contracts to verify whether a signature on a behalf of a given contract is valid. This is possible via the implementation of a &lt;code&gt;isValidSignature(hash, signature)&lt;&#x2F;code&gt; function on the signing contract, which can be called to validate a signature.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There are and will be many contracts that want to utilize signed messages for validation of rights-to-move assets or other purposes. In order for these contracts to be able to support non Externally Owned Accounts (i.e., contract owners), we need a standard mechanism by which a contract can indicate whether a given signature is valid or not on its behalf.&lt;&#x2F;p&gt;
&lt;p&gt;One example of an application that requires signatures to be provided would be decentralized exchanges with off-chain orderbook, where buy&#x2F;sell orders are signed messages. In these applications, EOAs sign orders, signaling their desire to buy&#x2F;sell a given asset and giving explicit permissions to the exchange smart contracts to conclude a trade via a signature. When it comes to contracts however, regular signatures are not possible since contracts do not possess a private key, hence this proposal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;RFC 2119&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ERC1271&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bytes4(keccak256(&amp;quot;isValidSignature(bytes32,bytes)&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; MAGICVALUE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x1626ba7e&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Should return whether the signature provided is valid for the provided hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Hash of the data to be signed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Signature byte array associated with _hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * MUST return the bytes4 magic value 0x1626ba7e when function passes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * MUST NOT modify state (using STATICCALL for solc &amp;lt; 0.5, view modifier for solc &amp;gt; 0.5)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * MUST allow external calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    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 class=&quot;z-entity z-name&quot;&gt;    returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; magicValue&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;isValidSignature&lt;&#x2F;code&gt; can call arbitrary methods to validate a given signature, which could be context dependent (e.g. time based or state based), EOA dependent (e.g. signers authorization level within smart wallet), signature scheme Dependent (e.g. ECDSA, multisig, BLS), etc.&lt;&#x2F;p&gt;
&lt;p&gt;This function should be implemented by contracts which desire to sign messages (e.g. smart contract wallets, DAOs, multisignature wallets, etc.) Applications wanting to support contract signatures should call this method if the signer is a contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;We believe the name of the proposed function to be appropriate considering that an &lt;em&gt;authorized&lt;&#x2F;em&gt; signers providing proper signatures for a given data would see their signature as &quot;valid&quot; by the signing contract. Hence, a signed action message is only valid when the signer is authorized to perform a given action on the behalf of a smart wallet.&lt;&#x2F;p&gt;
&lt;p&gt;Two arguments are provided for simplicity of separating the hash signed from the signature. A bytes32 hash is used instead of the unhashed message for simplicity, since contracts could expect a certain hashing function that is not standard, such as with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;isValidSignature()&lt;&#x2F;code&gt; should not be able to modify states in order to prevent &lt;code&gt;GasToken&lt;&#x2F;code&gt; minting or similar attack vectors. Again, this is to simplify the implementation surface of the function for better standardization and to allow off-chain contract queries.&lt;&#x2F;p&gt;
&lt;p&gt;The specific return value is expected to be returned instead of a boolean in order to have stricter and simpler verification of a signature.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is backward compatible with previous work on signature validation since this method is specific to contract based signatures and not EOA signatures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Example implementation of a signing contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Verifies that the signer is the owner of the signing contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; override&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Validate signatures&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;recoverSigner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x1626ba7e&lt;&#x2F;span&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;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xffffffff&lt;&#x2F;span&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;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 class=&quot;z-comment&quot;&gt; &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Recover the signer of hash, assuming it&amp;#39;s an EOA account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only for EthSign signatures&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;       Hash of message that was signed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Signature encoded as (bytes32 r, bytes32 s, uint8 v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; recoverSigner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&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 class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; signer&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;SignatureValidator#recoverSigner: invalid signature length&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Variables are not scoped in Solidity.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_signature&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;readBytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;readBytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; unique. Appendix F in the Ethereum Yellow paper (https:&#x2F;&#x2F;ethereum.github.io&#x2F;yellowpaper&#x2F;paper.pdf), defines&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the valid range for s in (281): 0 &amp;lt; s &amp;lt; secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; signatures from current libraries generate a unique signature with an s-value in the lower half order.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; vice versa. If your library also generates signatures with 0&#x2F;1 for v instead 27&#x2F;28, add 27 to v to accept&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; these malleable signatures as well.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Source OpenZeppelin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;OpenZeppelin&#x2F;openzeppelin-contracts&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;cryptography&#x2F;ECDSA.sol&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;SignatureValidator#recoverSigner: invalid signature &amp;#39;s&amp;#39; value&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;SignatureValidator#recoverSigner: invalid signature &amp;#39;v&amp;#39; value&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Recover ECDSA signer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    signer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ecrecover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Prevent signer from being 0x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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&gt;      signer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-string&quot;&gt;      &amp;quot;SignatureValidator#recoverSigner: INVALID_SIGNER&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&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; signer&lt;&#x2F;span&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;Example implementation of a contract calling the isValidSignature() function on an external signing contract ;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; callERC1271isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _signature&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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 class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC1271Wallet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isValidSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _signature&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x1626ba7e&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;INVALID_SIGNATURE&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Since there are no gas-limit expected for calling the isValidSignature() function, it is possible that some implementation will consume a large amount of gas. It is therefore important to not hardcode an amount of gas sent when calling this method on an external contract as it could prevent the validation of certain signatures.&lt;&#x2F;p&gt;
&lt;p&gt;Note also that each contract implementing this method is responsible to ensure that the signature passed is indeed valid, otherwise catastrophic outcomes are to be expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Constantinople Difficulty Bomb Delay and Block Reward Adjustment</title>
        <published>2018-07-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Afri Schoedon</name><uri>https://github.com/5chdn</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1234/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1234-constantinople-difficulty-bomb-delay-and-block-reward-adjustment/833" />
        

        <id>https://wg-eips.ritovision.com/1234/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1234"
            label="EIP-1234" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1234/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The average block times are increasing due to the difficulty bomb (also known as the &quot;&lt;em&gt;ice age&lt;&#x2F;em&gt;&quot;) slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately 12 months and to reduce the block rewards with the Constantinople fork, the second part of the Metropolis fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;CNSTNTNPL_FORK_BLKNUM&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 5 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 2 ETH, uncle and nephew rewards will be adjusted accordingly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The Casper development and switch to proof-of-stake is delayed, the Ethash proof-of-work should be feasible for miners and allow sealing new blocks every 15 seconds on average for another 12 months. With the delay of the ice age, there is a desire to not suddenly also increase miner rewards. The difficulty bomb has been known about for a long time and now it&#x27;s going to stop from happening. In order to maintain stability of the system, a block reward reduction that offsets the ice age delay would leave the system in the same general state as before. Reducing the reward also decreases the likelihood of a miner driven chain split as Ethereum approaches proof-of-stake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fake_block_number = max(0, block.number - 5_000_000) if block.number &amp;gt;= CNSTNTNPL_FORK_BLKNUM else block.number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;adjust-block-uncle-and-nephew-rewards&quot;&gt;Adjust Block, Uncle, and Nephew rewards&lt;&#x2F;h4&gt;
&lt;p&gt;To ensure a constant Ether issuance, adjust the block reward to &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;, where&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_block_reward = 2_000_000_000_000_000_000 if block.number &amp;gt;= CNSTNTNPL_FORK_BLKNUM else block.reward&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(2E18 wei, or 2,000,000,000,000,000,000 wei, or 2 ETH).&lt;&#x2F;p&gt;
&lt;p&gt;Analogue, if an uncle is included in a block for &lt;code&gt;block.number &amp;gt;= CNSTNTNPL_FORK_BLKNUM&lt;&#x2F;code&gt; such that &lt;code&gt;block.number - uncle.number = k&lt;&#x2F;code&gt;, the uncle reward is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_uncle_reward = (8 - k) * new_block_reward &#x2F; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the existing pre-Constantinople formula for uncle rewards, simply adjusted with &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The nephew reward for &lt;code&gt;block.number &amp;gt;= CNSTNTNPL_FORK_BLKNUM&lt;&#x2F;code&gt; is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_nephew_reward = new_block_reward &#x2F; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the existing pre-Constantinople formula for nephew rewards, simply adjusted with &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This will delay the ice age by 29 million seconds (approximately 12 months), so the chain would be back at 30 second block times in winter 2019. An alternate proposal was to add special rules to the difficulty calculation to effectively &lt;em&gt;pause&lt;&#x2F;em&gt; the difficulty between different blocks. This would lead to similar results.&lt;&#x2F;p&gt;
&lt;p&gt;This was previously discussed at All Core Devs Meeting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;6dbd82303bfcb697eaf9a76de37f5fa570e6379d&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2042.md&quot;&gt;#42&lt;&#x2F;a&gt; and subsequent meetings; and accepted in the Constantinople Session &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;issues&#x2F;55&quot;&gt;#1&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It&#x27;s suggested to include this EIP in the second Metropolis hard-fork, &lt;em&gt;Constantinople&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation in it&#x27;s logic does not differ from &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;649&#x2F;&quot;&gt;EIP-649&lt;&#x2F;a&gt;; an implementation for Parity-Ethereum is available in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity-ethereum&#x2F;pull&#x2F;9187&quot;&gt;parity-ethereum#9187&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum Provider JavaScript API</title>
        <published>2018-06-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Fabian Vogelsteller</name><uri>https://github.com/frozeman</uri>
	</author>
	
	<author>
		<name>Ryan Ghods</name><uri>https://github.com/ryanio</uri>
	</author>
	
	<author>
		<name>Victor Maia</name><uri>https://github.com/MaiaVictor</uri>
	</author>
	
	<author>
		<name>Marc Garreau</name><uri>https://github.com/wolovim</uri>
	</author>
	
	<author>
		<name>Erik Marks</name><uri>https://github.com/rekmarks</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1193/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/2319" />
        

        <id>https://wg-eips.ritovision.com/1193/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1193"
            label="EIP-1193" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1193/">&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A JavaScript Ethereum Provider API for consistency across clients and applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;A common convention in the Ethereum web application (&quot;dapp&quot;) ecosystem is for key management software (&quot;wallets&quot;) to expose their API via a JavaScript object in the web page.
This object is called &quot;the Provider&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Historically, Provider implementations have exhibited conflicting interfaces and behaviors between wallets.
This EIP formalizes an Ethereum Provider API to promote wallet interoperability.
The API is designed to be minimal, event-driven, and agnostic of transport and RPC protocols.
Its functionality is easily extended by defining new RPC methods and &lt;code&gt;message&lt;&#x2F;code&gt; event types.&lt;&#x2F;p&gt;
&lt;p&gt;Historically, Providers have been made available as &lt;code&gt;window.ethereum&lt;&#x2F;code&gt; in web browsers, but this convention is not part of the specification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;RFC-2119&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Comments like this are non-normative.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;This section is non-normative.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provider
&lt;ul&gt;
&lt;li&gt;A JavaScript object made available to a consumer, that provides access to Ethereum by means of a Client.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Client
&lt;ul&gt;
&lt;li&gt;An endpoint that receives Remote Procedure Call (RPC) requests from the Provider, and returns their results.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Wallet
&lt;ul&gt;
&lt;li&gt;An end-user application that manages private keys, performs signing operations, and acts as a middleware between the Provider and the Client.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Remote Procedure Call (RPC)
&lt;ul&gt;
&lt;li&gt;A Remote Procedure Call (RPC), is any request submitted to a Provider for some procedure that is to be processed by a Provider, its Wallet, or its Client.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;connectivity&quot;&gt;Connectivity&lt;&#x2F;h3&gt;
&lt;p&gt;The Provider is said to be &quot;connected&quot; when it can service RPC requests to at least one chain.&lt;&#x2F;p&gt;
&lt;p&gt;The Provider is said to be &quot;disconnected&quot; when it cannot service RPC requests to any chain at all.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To service an RPC request, the Provider must successfully submit the request to the remote location, and receive a response.
In other words, if the Provider is unable to communicate with its Client, for example due to network issues, the Provider is disconnected.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;api&quot;&gt;API&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The Provider API is specified using TypeScript.
The authors encourage implementers to declare their own types and interfaces, using the ones in this section as a basis.&lt;&#x2F;p&gt;
&lt;p&gt;For consumer-facing API documentation, see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#appendix-i-consumer-facing-api-documentation&quot;&gt;Appendix I&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement and expose the API defined in this section.
All API entities &lt;strong&gt;MUST&lt;&#x2F;strong&gt; adhere to the types and interfaces defined in this section.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;request&quot;&gt;request&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;request&lt;&#x2F;code&gt; method is intended as a transport- and protocol-agnostic wrapper function for Remote Procedure Calls (RPCs).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RequestArguments&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; object&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;RequestArguments&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Promise&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;unknown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&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 Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; identify the requested RPC method by the value of &lt;code&gt;RequestArguments.method&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the requested RPC method takes any parameters, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; accept them as the value of &lt;code&gt;RequestArguments.params&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;RPC requests &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be handled such that the returned Promise either resolves with a value per the requested RPC method&#x27;s specification, or rejects with an error.&lt;&#x2F;p&gt;
&lt;p&gt;If resolved, the Promise &lt;strong&gt;MUST&lt;&#x2F;strong&gt; resolve with a result per the RPC method&#x27;s specification. The Promise &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; resolve with any RPC protocol-specific response objects, unless the RPC method&#x27;s return type is so defined.&lt;&#x2F;p&gt;
&lt;p&gt;If the returned Promise rejects, it &lt;strong&gt;MUST&lt;&#x2F;strong&gt; reject with a &lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt; as specified in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#rpc-errors&quot;&gt;RPC Errors&lt;&#x2F;a&gt; section below.&lt;&#x2F;p&gt;
&lt;p&gt;The returned Promise &lt;strong&gt;MUST&lt;&#x2F;strong&gt; reject if any of the following conditions are met:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An error is returned for the RPC request.
&lt;ul&gt;
&lt;li&gt;If the returned error is compatible with the &lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt; interface, the Promise &lt;strong&gt;MAY&lt;&#x2F;strong&gt; reject with that error directly.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The Provider encounters an error or fails to process the request for any reason.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;If the Provider implements any kind of authorization logic, the authors recommend rejecting with a &lt;code&gt;4100&lt;&#x2F;code&gt; error in case of authorization failures.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The returned Promise &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; reject if any of the following conditions are met:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The Provider is disconnected.
&lt;ul&gt;
&lt;li&gt;If rejecting for this reason, the Promise rejection error &lt;code&gt;code&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be &lt;code&gt;4900&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The RPC request is directed at a specific chain, and the Provider is not connected to that chain, but is connected to at least one other chain.
&lt;ul&gt;
&lt;li&gt;If rejecting for this reason, the Promise rejection error &lt;code&gt;code&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be &lt;code&gt;4901&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;See the section &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#connectivity&quot;&gt;Connectivity&lt;&#x2F;a&gt; for the definitions of &quot;connected&quot; and &quot;disconnected&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;supported-rpc-methods&quot;&gt;Supported RPC Methods&lt;&#x2F;h3&gt;
&lt;p&gt;A &quot;supported RPC method&quot; is any RPC method that may be called via the Provider.&lt;&#x2F;p&gt;
&lt;p&gt;All supported RPC methods &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be identified by unique strings.&lt;&#x2F;p&gt;
&lt;p&gt;Providers &lt;strong&gt;MAY&lt;&#x2F;strong&gt; support whatever RPC methods required to fulfill their purpose, standardized or otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;If an RPC method defined in a finalized EIP is not supported, it &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; be rejected with a &lt;code&gt;4200&lt;&#x2F;code&gt; error per the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#provider-errors&quot;&gt;Provider Errors&lt;&#x2F;a&gt; section below, or an appropriate error per the RPC method&#x27;s specification.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;rpc-errors&quot;&gt;RPC Errors&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderRpcError&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  code&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;ul&gt;
&lt;li&gt;&lt;code&gt;message&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be a human-readable string&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; adhere to the specifications in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#error-standards&quot;&gt;Error Standards&lt;&#x2F;a&gt; section below&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;code&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;&#x2F;strong&gt; be an integer number&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; adhere to the specifications in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#error-standards&quot;&gt;Error Standards&lt;&#x2F;a&gt; section below&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;data&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; contain any other useful information about the error&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;error-standards&quot;&gt;Error Standards&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt; codes and messages &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; follow these conventions, in order of priority:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The errors in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#provider-errors&quot;&gt;Provider Errors&lt;&#x2F;a&gt; section below&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any errors mandated by the erroring RPC method&#x27;s specification&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;CloseEvent#Status_codes&quot;&gt;&lt;code&gt;CloseEvent&lt;&#x2F;code&gt; status codes&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;provider-errors&quot;&gt;Provider Errors&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Status code&lt;&#x2F;th&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;4001&lt;&#x2F;td&gt;&lt;td&gt;User Rejected Request&lt;&#x2F;td&gt;&lt;td&gt;The user rejected the request.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4100&lt;&#x2F;td&gt;&lt;td&gt;Unauthorized&lt;&#x2F;td&gt;&lt;td&gt;The requested method and&#x2F;or account has not been authorized by the user.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4200&lt;&#x2F;td&gt;&lt;td&gt;Unsupported Method&lt;&#x2F;td&gt;&lt;td&gt;The Provider does not support the requested method.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4900&lt;&#x2F;td&gt;&lt;td&gt;Disconnected&lt;&#x2F;td&gt;&lt;td&gt;The Provider is disconnected from all chains.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4901&lt;&#x2F;td&gt;&lt;td&gt;Chain Disconnected&lt;&#x2F;td&gt;&lt;td&gt;The Provider is not connected to the requested chain.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;4900&lt;&#x2F;code&gt; is intended to indicate that the Provider is disconnected from all chains, while &lt;code&gt;4901&lt;&#x2F;code&gt; is intended to indicate that the Provider is disconnected from a specific chain only.
In other words, &lt;code&gt;4901&lt;&#x2F;code&gt; implies that the Provider is connected to other chains, just not the requested one.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;p&gt;The Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; implement the following event handling methods:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;on&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;removeListener&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These methods &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be implemented per the Node.js &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;api&#x2F;events.html&quot;&gt;&lt;code&gt;EventEmitter&lt;&#x2F;code&gt; API&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To satisfy these requirements, Provider implementers should consider simply extending the Node.js &lt;code&gt;EventEmitter&lt;&#x2F;code&gt; class and bundling it for the target environment.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;message&quot;&gt;message&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;message&lt;&#x2F;code&gt; event is intended for arbitrary notifications not covered by other events.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;When emitted, the &lt;code&gt;message&lt;&#x2F;code&gt; event &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be emitted with an object argument of the following form:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderMessage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;h5 id=&quot;subscriptions&quot;&gt;Subscriptions&lt;&#x2F;h5&gt;
&lt;p&gt;If the Provider supports Ethereum RPC subscriptions, e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;geth.ethereum.org&#x2F;docs&#x2F;rpc&#x2F;pubsub&quot;&gt;&lt;code&gt;eth_subscribe&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit the &lt;code&gt;message&lt;&#x2F;code&gt; event when it receives a subscription notification.&lt;&#x2F;p&gt;
&lt;p&gt;If the Provider receives a subscription message from e.g. an &lt;code&gt;eth_subscribe&lt;&#x2F;code&gt; subscription, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit a &lt;code&gt;message&lt;&#x2F;code&gt; event with a &lt;code&gt;ProviderMessage&lt;&#x2F;code&gt; object of the following form:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; EthSubscription&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; ProviderMessage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_subscription&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-storage&quot;&gt;    readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subscription&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;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;h4 id=&quot;connect&quot;&gt;connect&lt;&#x2F;h4&gt;
&lt;p&gt;See the section &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#connectivity&quot;&gt;Connectivity&lt;&#x2F;a&gt; for the definition of &quot;connected&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;If the Provider becomes connected, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit the event named &lt;code&gt;connect&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This includes when:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The Provider first connects to a chain after initialization.&lt;&#x2F;li&gt;
&lt;li&gt;The Provider connects to a chain after the &lt;code&gt;disconnect&lt;&#x2F;code&gt; event was emitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This event &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be emitted with an object of the following form:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderConnectInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;&lt;code&gt;chainId&lt;&#x2F;code&gt; &lt;strong&gt;MUST&lt;&#x2F;strong&gt; specify the integer ID of the connected chain as a hexadecimal string, per the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;695&#x2F;&quot;&gt;&lt;code&gt;eth_chainId&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; Ethereum RPC method.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;disconnect&quot;&gt;disconnect&lt;&#x2F;h4&gt;
&lt;p&gt;See the section &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#connectivity&quot;&gt;Connectivity&lt;&#x2F;a&gt; for the definition of &quot;disconnected&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;If the Provider becomes disconnected from all chains, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit the event named &lt;code&gt;disconnect&lt;&#x2F;code&gt; with value &lt;code&gt;error: ProviderRpcError&lt;&#x2F;code&gt;, per the interfaced defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#rpc-errors&quot;&gt;RPC Errors&lt;&#x2F;a&gt; section. The value of the error&#x27;s &lt;code&gt;code&lt;&#x2F;code&gt; property &lt;strong&gt;MUST&lt;&#x2F;strong&gt; follow the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;CloseEvent#Status_codes&quot;&gt;status codes for &lt;code&gt;CloseEvent&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;chainchanged&quot;&gt;chainChanged&lt;&#x2F;h4&gt;
&lt;p&gt;If the chain the Provider is connected to changes, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit the event named &lt;code&gt;chainChanged&lt;&#x2F;code&gt; with value &lt;code&gt;chainId: string&lt;&#x2F;code&gt;, specifying the integer ID of the new chain as a hexadecimal string, per the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;695&#x2F;&quot;&gt;&lt;code&gt;eth_chainId&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; Ethereum RPC method.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;accountschanged&quot;&gt;accountsChanged&lt;&#x2F;h4&gt;
&lt;p&gt;If the accounts available to the Provider change, the Provider &lt;strong&gt;MUST&lt;&#x2F;strong&gt; emit the event named &lt;code&gt;accountsChanged&lt;&#x2F;code&gt; with value &lt;code&gt;accounts: string[]&lt;&#x2F;code&gt;, containing the account addresses per the &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; Ethereum RPC method.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;accounts available to the Provider&quot; change when the return value of &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The purpose of a Provider is to &lt;em&gt;provide&lt;&#x2F;em&gt; a consumer with access to Ethereum.
In general, a Provider must enable an Ethereum web application to do two things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Make Ethereum RPC requests&lt;&#x2F;li&gt;
&lt;li&gt;Respond to state changes in the Provider&#x27;s Ethereum chain, Client, and Wallet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Provider API specification consists of a single method and five events.
The &lt;code&gt;request&lt;&#x2F;code&gt; method and the &lt;code&gt;message&lt;&#x2F;code&gt; event alone, are sufficient to implement a complete Provider.
They are designed to make arbitrary RPC requests and communicate arbitrary messages, respectively.&lt;&#x2F;p&gt;
&lt;p&gt;The remaining four events can be separated into two categories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Changes to the Provider&#x27;s ability to make RPC requests
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;connect&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;disconnect&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Common Client and&#x2F;or Wallet state changes that any non-trivial application must handle
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;chainChanged&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;accountsChanged&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These events are included due to the widespread production usage of related patterns, at the time of writing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Many Providers adopted a draft version of this specification before it was finalized.
The current API is designed to be a strict superset of the legacy version, and this specification is in that sense fully backwards compatible.
See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#appendix-iii-legacy-provider-api&quot;&gt;Appendix III&lt;&#x2F;a&gt; for the legacy API.&lt;&#x2F;p&gt;
&lt;p&gt;Providers that only implement this specification will not be compatible with Ethereum web applications that target the legacy API.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementations&quot;&gt;Implementations&lt;&#x2F;h2&gt;
&lt;p&gt;At the time of writing, the following projects have working implementations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nomiclabs&#x2F;buidler&#x2F;pull&#x2F;608&quot;&gt;buidler.dev&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethers-io&#x2F;ethers.js&#x2F;blob&#x2F;56af4413b1dd1787db68985e0b612b63d86fdf7c&#x2F;packages&#x2F;providers&#x2F;src.ts&#x2F;web3-provider.ts&quot;&gt;ethers.js&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;eth-provider&quot;&gt;eth-provider&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MetaMask&#x2F;inpage-provider&quot;&gt;MetaMask&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;WalletConnect&#x2F;walletconnect-monorepo&#x2F;blob&#x2F;d33fd2070d7a67f74de50fd10ca4217f4e2f22f3&#x2F;packages&#x2F;providers&#x2F;web3-provider&#x2F;README.md&quot;&gt;WalletConnect&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web3js.readthedocs.io&#x2F;&quot;&gt;web3.js&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;The Provider is intended to pass messages between an Ethereum Client and an Ethereum application.
It is &lt;em&gt;not&lt;&#x2F;em&gt; responsible for private key or account management; it merely processes RPC messages and emits events.
Consequently, account security and user privacy need to be implemented in middlewares between the Provider and its Ethereum Client.
In practice, we call these middleware applications &quot;Wallets,&quot; and they usually manage the user&#x27;s private keys and accounts.
The Provider can be thought of as an extension of the Wallet, exposed in an untrusted environment, under the control of some third party (e.g. a website).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;handling-adversarial-behavior&quot;&gt;Handling Adversarial Behavior&lt;&#x2F;h3&gt;
&lt;p&gt;Since it is a JavaScript object, consumers can generally perform arbitrary operations on the Provider, and all its properties can be read or overwritten.
Therefore, it is best to treat the Provider object as though it is controlled by an adversary.
It is paramount that the Provider implementer protects the user, Wallet, and Client by ensuring that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The Provider does not contain any private user data.&lt;&#x2F;li&gt;
&lt;li&gt;The Provider and Wallet programs are isolated from each other.&lt;&#x2F;li&gt;
&lt;li&gt;The Wallet and&#x2F;or Client rate-limit requests from the Provider.&lt;&#x2F;li&gt;
&lt;li&gt;The Wallet and&#x2F;or Client validate all data sent from the Provider.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;chain-changes&quot;&gt;Chain Changes&lt;&#x2F;h3&gt;
&lt;p&gt;Since all Ethereum operations are directed at a particular chain, it&#x27;s important that the Provider accurately reflects the Client&#x27;s configured chain, per the &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; Ethereum RPC method (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;695&#x2F;&quot;&gt;EIP-695&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;This includes ensuring that &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; has the correct return value, and that the &lt;code&gt;chainChanged&lt;&#x2F;code&gt; event is emitted whenever that value changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;user-account-exposure-and-account-changes&quot;&gt;User Account Exposure and Account Changes&lt;&#x2F;h3&gt;
&lt;p&gt;Many Ethereum write operations (e.g. &lt;code&gt;eth_sendTransaction&lt;&#x2F;code&gt;) require a user account to be specified.
Provider consumers access these accounts via the &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; RPC method, and by listening for the &lt;code&gt;accountsChanged&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;As with &lt;code&gt;eth_chainId&lt;&#x2F;code&gt;, it is critical that &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; has the correct return value, and that the &lt;code&gt;accountsChanged&lt;&#x2F;code&gt; event is emitted whenever that value changes.&lt;&#x2F;p&gt;
&lt;p&gt;The return value of &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; is ultimately controlled by the Wallet or Client.
In order to protect user privacy, the authors recommend not exposing any accounts by default.
Instead, Providers should support RPC methods for explicitly requesting account access, such as &lt;code&gt;eth_requestAccounts&lt;&#x2F;code&gt; (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1102&#x2F;&quot;&gt;EIP-1102&lt;&#x2F;a&gt;) or &lt;code&gt;wallet_requestPermissions&lt;&#x2F;code&gt; (see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2255&#x2F;&quot;&gt;EIP-2255&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;interfaces&#x2F;issues&#x2F;16&quot;&gt;Initial discussion in &lt;code&gt;ethereum&#x2F;interfaces&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;eip-1193-ethereum-provider-javascript-api&#x2F;640&quot;&gt;Deprecated Ethereum Magicians thread&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;2319&quot;&gt;Continuing discussion&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Related EIPs
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1102&#x2F;&quot;&gt;EIP-1102: Opt-in Account Exposure&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1474&#x2F;&quot;&gt;EIP-1474: Remote Procedure Call Specification&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1767&#x2F;&quot;&gt;EIP-1767: GraphQL Interface to Ethereum Node Data&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2255&#x2F;&quot;&gt;EIP-2255: Wallet Permissions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-i-consumer-facing-api-documentation&quot;&gt;Appendix I: Consumer-Facing API Documentation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;request-1&quot;&gt;request&lt;&#x2F;h3&gt;
&lt;p&gt;Makes an Ethereum RPC method call.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RequestArguments&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; object&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;RequestArguments&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;Promise&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;unknown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&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 returned Promise resolves with the method&#x27;s result or rejects with a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#errors&quot;&gt;&lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&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;Consult each Ethereum RPC method&#x27;s documentation for its &lt;code&gt;params&lt;&#x2F;code&gt; and return type.
You can find a list of common methods &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1474&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;rpc-protocols&quot;&gt;RPC Protocols&lt;&#x2F;h4&gt;
&lt;p&gt;Multiple RPC protocols may be available. For examples, see:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1474&#x2F;&quot;&gt;EIP-1474&lt;&#x2F;a&gt;, the Ethereum JSON-RPC API&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1767&#x2F;&quot;&gt;EIP-1767&lt;&#x2F;a&gt;, the Ethereum GraphQL schema&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;events-1&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;p&gt;Events follow the conventions of the Node.js &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;api&#x2F;events.html&quot;&gt;&lt;code&gt;EventEmitter&lt;&#x2F;code&gt; API&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;connect-1&quot;&gt;connect&lt;&#x2F;h4&gt;
&lt;p&gt;The Provider emits &lt;code&gt;connect&lt;&#x2F;code&gt; when it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;first connects to a chain after being initialized.&lt;&#x2F;li&gt;
&lt;li&gt;first connects to a chain, after the &lt;code&gt;disconnect&lt;&#x2F;code&gt; event was emitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderConnectInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;connect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;connectInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderConnectInfo&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&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 event emits an object with a hexadecimal string &lt;code&gt;chainId&lt;&#x2F;code&gt; per the &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; Ethereum RPC method, and other properties as determined by the Provider.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;disconnect-1&quot;&gt;disconnect&lt;&#x2F;h4&gt;
&lt;p&gt;The Provider emits &lt;code&gt;disconnect&lt;&#x2F;code&gt; when it becomes disconnected from all chains.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;disconnect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderRpcError&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&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 event emits a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#errors&quot;&gt;&lt;code&gt;ProviderRpcError&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. The error &lt;code&gt;code&lt;&#x2F;code&gt; follows the table of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;CloseEvent#Status_codes&quot;&gt;&lt;code&gt;CloseEvent&lt;&#x2F;code&gt; status codes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;chainchanged-1&quot;&gt;chainChanged&lt;&#x2F;h4&gt;
&lt;p&gt;The Provider emits &lt;code&gt;chainChanged&lt;&#x2F;code&gt; when connecting to a new chain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;chainChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&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 event emits a hexadecimal string &lt;code&gt;chainId&lt;&#x2F;code&gt; per the &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; Ethereum RPC method.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;accountschanged-1&quot;&gt;accountsChanged&lt;&#x2F;h4&gt;
&lt;p&gt;The Provider emits &lt;code&gt;accountsChanged&lt;&#x2F;code&gt; if the accounts returned from the Provider (&lt;code&gt;eth_accounts&lt;&#x2F;code&gt;) change.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;accountsChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&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 event emits with &lt;code&gt;accounts&lt;&#x2F;code&gt;, an array of account addresses, per the &lt;code&gt;eth_accounts&lt;&#x2F;code&gt; Ethereum RPC method.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;message-1&quot;&gt;message&lt;&#x2F;h4&gt;
&lt;p&gt;The Provider emits &lt;code&gt;message&lt;&#x2F;code&gt; to communicate arbitrary messages to the consumer.
Messages may include JSON-RPC notifications, GraphQL subscriptions, and&#x2F;or any other event as defined by the Provider.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderMessage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; listener&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderMessage&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;subscriptions-1&quot;&gt;Subscriptions&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;geth.ethereum.org&#x2F;docs&#x2F;rpc&#x2F;pubsub&quot;&gt;&lt;code&gt;eth_&lt;&#x2F;code&gt; subscription methods&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;wiki&#x2F;Whisper-v6-RPC-API#shh_subscribe&quot;&gt;&lt;code&gt;shh_&lt;&#x2F;code&gt; subscription methods&lt;&#x2F;a&gt; rely on this event to emit subscription updates.&lt;&#x2F;p&gt;
&lt;p&gt;For e.g. &lt;code&gt;eth_subscribe&lt;&#x2F;code&gt; subscription updates, &lt;code&gt;ProviderMessage.type&lt;&#x2F;code&gt; will equal the string &lt;code&gt;&#x27;eth_subscription&#x27;&lt;&#x2F;code&gt;, and the subscription data will be the value of &lt;code&gt;ProviderMessage.data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;errors&quot;&gt;Errors&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ProviderRpcError&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  code&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; unknown&lt;&#x2F;span&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;h2 id=&quot;appendix-ii-examples&quot;&gt;Appendix II: Examples&lt;&#x2F;h2&gt;
&lt;p&gt;These examples assume a web browser environment.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Most Providers are available as window.ethereum on page load.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is only a convention, not a standard, and may not be the case in practice.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Please consult the Provider implementation&amp;#39;s documentation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; ethereum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 1: Log chainId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&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 class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hexadecimal string: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;decimal number: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;parseInt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;chainId&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Error fetching chainId: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 2: Log last block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&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 class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&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&gt;    method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_getBlockByNumber&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;    params&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;latest&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;block&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Block &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Error fetching last block: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;       Code: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;. Data: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&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;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;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 3: Log available accounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&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 class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Accounts:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;join&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Error fetching accounts: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;       Code: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;. Data: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&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;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;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 4: Log new blocks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&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 class=&quot;z-entity z-name&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&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&gt;    method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_subscribe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;    params&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;newHeads&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subscriptionId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    ethereum&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-keyword&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eth_subscription&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;subscription&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; subscriptionId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;          if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; typeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;result&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;            console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;New block &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;number&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; block&lt;&#x2F;span&gt;&lt;span&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&gt;          }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable z-other&quot;&gt;            console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Something went wrong: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&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;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;span&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&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&gt;  .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;    console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;      `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Error making newHeads subscription: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;       Code: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;. Data: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&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;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;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 5: Log when accounts change&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; logAccounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;  console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Accounts:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;accounts&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;join&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;ethereum&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;accountsChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; logAccounts&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; to unsubscribe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;removeListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;accountsChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; logAccounts&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Example 6: Log if connection ends&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ethereum&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;disconnect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;code&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; reason&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;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 class=&quot;z-variable z-other&quot;&gt;  console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Ethereum Provider connection closed: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;reason&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;. Code: &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&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;appendix-iii-legacy-provider-api&quot;&gt;Appendix III: Legacy Provider API&lt;&#x2F;h2&gt;
&lt;p&gt;This section documents the legacy Provider API, which is extensively used in production at the time of writing.
As it was never fully standardized, significant deviations occur in practice.
The authors recommend against implementing it except to support legacy Ethereum applications.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sendasync-deprecated&quot;&gt;sendAsync (DEPRECATED)&lt;&#x2F;h3&gt;
&lt;p&gt;This method is superseded by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#request&quot;&gt;&lt;code&gt;request&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;sendAsync&lt;&#x2F;code&gt; is like &lt;code&gt;request&lt;&#x2F;code&gt;, but with JSON-RPC objects and a callback.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sendAsync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;request&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Object&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; callback&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;void&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;Historically, the request and response object interfaces have followed the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1474&#x2F;&quot;&gt;Ethereum JSON-RPC specification&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;send-deprecated&quot;&gt;send (DEPRECATED)&lt;&#x2F;h3&gt;
&lt;p&gt;This method is superseded by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#request&quot;&gt;&lt;code&gt;request&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;unknown&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;unknown&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;legacy-events&quot;&gt;Legacy Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;close-deprecated&quot;&gt;close (DEPRECATED)&lt;&#x2F;h4&gt;
&lt;p&gt;This event is superseded by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#disconnect&quot;&gt;&lt;code&gt;disconnect&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;networkchanged-deprecated&quot;&gt;networkChanged (DEPRECATED)&lt;&#x2F;h4&gt;
&lt;p&gt;The event &lt;code&gt;networkChanged&lt;&#x2F;code&gt; is superseded by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#chainchanged&quot;&gt;&lt;code&gt;chainChanged&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For details, see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155: Simple replay attack protection&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;695&#x2F;&quot;&gt;EIP-695: Create eth_chainId method for JSON-RPC&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;notification-deprecated&quot;&gt;notification (DEPRECATED)&lt;&#x2F;h4&gt;
&lt;p&gt;This event is superseded by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1193&#x2F;#message&quot;&gt;&lt;code&gt;message&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Historically, this event has been emitted with e.g. &lt;code&gt;eth_subscribe&lt;&#x2F;code&gt; subscription updates of the form &lt;code&gt;{ subscription: string, result: unknown }&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Minimal Proxy Contract</title>
        <published>2018-06-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Peter Murray</name><uri>https://github.com/yarrumretep</uri>
	</author>
	
	<author>
		<name>Nate Welch</name><uri>https://github.com/flygoing</uri>
	</author>
	
	<author>
		<name>Joe Messerman</name><uri>https://github.com/JAMesserman</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1167/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/optionality/clone-factory/issues/10" />
        

        <id>https://wg-eips.ritovision.com/1167/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1167"
            label="ERC-1167" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1167/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;To simply and cheaply clone contract functionality in an immutable way, this standard specifies a minimal bytecode implementation that delegates all calls to a known, fixed address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;By standardizing on a known minimal bytecode redirect implementation, this standard allows users and third party tools (e.g. Etherscan) to (a) simply discover that a contract will always redirect in a known manner and (b) depend on the behavior of the code at the destination contract as the behavior of the redirecting contract.  Specifically, tooling can interrogate the bytecode at a redirecting address to determine the location of the code that will run - and can depend on representations about that code (verified source, third-party audits, etc).  This implementation forwards all calls and 100% of the gas to the implementation contract and then relays the return value back to the caller.  In the case where the implementation reverts, the revert is passed back along with the payload data (for revert with message).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This standard supports use-cases wherein it is desirable to clone exact contract functionality with a minimum of side effects (e.g. memory slot stomping) and with low gas cost deployment of duplicate proxies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The exact bytecode of the standard clone contract is this: &lt;code&gt;363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3&lt;&#x2F;code&gt; wherein the bytes at indices 10 - 29 (inclusive) are replaced with the 20 byte address of the master functionality contract.&lt;&#x2F;p&gt;
&lt;p&gt;A reference implementation of this can be found at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;optionality&#x2F;clone-factory&quot;&gt;optionality&#x2F;clone-factory&lt;&#x2F;a&gt; github repo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The goals of this effort have been the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;inexpensive deployment (low gas to deploy clones)&lt;&#x2F;li&gt;
&lt;li&gt;support clone initialization in creation transaction (through factory contract model)&lt;&#x2F;li&gt;
&lt;li&gt;simple clone bytecode to encourage directly bytecode interrogation (see CloneProbe.sol in the clone-factory project)&lt;&#x2F;li&gt;
&lt;li&gt;dependable, locked-down behavior - this is not designed to handle upgradability, nor should it as the representation we are seeking is stronger.&lt;&#x2F;li&gt;
&lt;li&gt;small operational overhead - adds a single call cost to each call&lt;&#x2F;li&gt;
&lt;li&gt;handles error return bubbling for revert messages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no backwards compatibility issues.  There may be some systems that are using earlier versions of the proxy contract bytecode.  They will not be compliant with this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;invocation with no arguments&lt;&#x2F;li&gt;
&lt;li&gt;invocation with arguments&lt;&#x2F;li&gt;
&lt;li&gt;invocation with fixed length return values&lt;&#x2F;li&gt;
&lt;li&gt;invocation with variable length return values&lt;&#x2F;li&gt;
&lt;li&gt;invocation with revert (confirming reverted payload is transferred)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Tests for these cases are included in the reference implementation project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Deployment bytecode is not included in this specification.  One approach is defined in the proxy-contract reference implementation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;standard-proxy&quot;&gt;Standard Proxy&lt;&#x2F;h3&gt;
&lt;p&gt;The disassembly of the standard deployed proxy contract code (from r2 and edited to include stack visualization)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000000      36             calldatasize          cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000001      3d             returndatasize        0 cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000002      3d             returndatasize        0 0 cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000003      37             calldatacopy          &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000004      3d             returndatasize        0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000005      3d             returndatasize        0 0 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000006      3d             returndatasize        0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000007      36             calldatasize          cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000008      3d             returndatasize        0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000009      73bebebebebe.  push20 0xbebebebe     0xbebe 0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001e      5a             gas                   gas 0xbebe 0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001f      f4             delegatecall          suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000020      3d             returndatasize        rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000021      82             dup3                  0 rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000022      80             dup1                  0 0 rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000023      3e             returndatacopy        suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000024      90             swap1                 0 suc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000025      3d             returndatasize        rds 0 suc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000026      91             swap2                 suc 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000027      602b           push1 0x2b            0x2b suc 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       ,=&amp;lt; 0x00000029      57             jumpi                 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |   0x0000002a      fd             revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       `-&amp;gt; 0x0000002b      5b             jumpdest              0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\           0x0000002c      f3             return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NOTE: as an effort to reduce gas costs as much as possible, the above bytecode depends on EIP-211 specification that &lt;code&gt;returndatasize&lt;&#x2F;code&gt; returns zero prior to any calls within the call-frame. &lt;code&gt;returndatasize&lt;&#x2F;code&gt; uses 1 less gas than &lt;code&gt;dup*&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vanity-address-optimization&quot;&gt;Vanity Address Optimization&lt;&#x2F;h3&gt;
&lt;p&gt;Proxy deployment can be further optimized by installing the master contract at a vanity contract deployment address with leading zero-bytes.  By generating a master contract vanity address that includes Z leading 0 bytes in its address, you can shorten the proxy bytecode by replacing the &lt;code&gt;push20&lt;&#x2F;code&gt; opcode with &lt;code&gt;pushN&lt;&#x2F;code&gt; (where N is 20 - Z) followed by the N non-zero address bytes.  The revert jump address is decremented by Z in this case.  Here is an example where Z = 4:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000000      36             calldatasize          cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000001      3d             returndatasize        0 cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000002      3d             returndatasize        0 0 cds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000003      37             calldatacopy          &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000004      3d             returndatasize        0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000005      3d             returndatasize        0 0 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000006      3d             returndatasize        0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000007      36             calldatasize          cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000008      3d             returndatasize        0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000009      6fbebebebebe.  push16 0xbebebebe     0xbebe 0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001a      5a             gas                   gas 0xbebe 0 cds 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001b      f4             delegatecall          suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001c      3d             returndatasize        rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001d      82             dup3                  0 rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001e      80             dup1                  0 0 rds suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x0000001f      3e             returndatacopy        suc 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000020      90             swap1                 0 suc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000021      3d             returndatasize        rds 0 suc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000022      91             swap2                 suc 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|           0x00000023      6027           push1 0x27            0x27 suc 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       ,=&amp;lt; 0x00000025      57             jumpi                 0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       |   0x00000026      fd             revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       `-&amp;gt; 0x00000027      5b             jumpdest              0 rds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\           0x00000028      f3             return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This saves 4 bytes of proxy contract size (savings on each deployment) and has zero impact on runtime gas costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Multi Token Standard</title>
        <published>2018-06-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Witek Radomski</name><email>witek@enjin.io</email>
	</author>
	
	<author>
		<name>Andrew Cooke</name><email>ac0dem0nk3y@gmail.com</email>
	</author>
	
	<author>
		<name>Philippe Castonguay</name><uri>https://github.com/phabc</uri><email>pc@horizongames.net</email>
	</author>
	
	<author>
		<name>James Therien</name><email>james@turing-complete.com</email>
	</author>
	
	<author>
		<name>Eric Binet</name><email>eric@enjin.io</email>
	</author>
	
	<author>
		<name>Ronan Sandford</name><uri>https://github.com/wighawag</uri><email>wighawag@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1155/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/1155" />
        

        <id>https://wg-eips.ritovision.com/1155/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:1155"
            label="ERC-1155" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1155/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens or other configurations (e.g. semi-fungible tokens).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard outlines a smart contract interface that can represent any number of fungible and non-fungible token types. Existing standards such as ERC-20 require deployment of separate contracts per token type. The ERC-721 standard&#x27;s token ID is a single non-fungible index and the group of these non-fungibles is deployed as a single contract with settings for the entire collection. In contrast, the ERC-1155 Multi Token Standard allows for each token ID to represent a new configurable token type, which may have its own metadata, supply and other attributes.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;_id&lt;&#x2F;code&gt; argument contained in each function&#x27;s argument set indicates a specific token or token type in a transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Tokens standards like ERC-20 and ERC-721 require a separate contract to be deployed for each token type or collection. This places a lot of redundant bytecode on the Ethereum blockchain and limits certain functionality by the nature of separating each token contract into its own permissioned address. With the rise of blockchain games and platforms like Enjin Coin, game developers may be creating thousands of token types, and a new type of token standard is needed to support them. However, ERC-1155 is not specific to games and many other applications can benefit from this flexibility.&lt;&#x2F;p&gt;
&lt;p&gt;New functionality is possible with this design such as transferring multiple token types at once, saving on transaction costs. Trading (escrow &#x2F; atomic swaps) of multiple tokens can be built on top of this standard and it removes the need to &quot;approve&quot; individual token contracts separately. It is also easy to describe and mix multiple fungible or non-fungible token types in a single contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Smart contracts implementing the ERC-1155 standard MUST implement all of the functions in the &lt;code&gt;ERC1155&lt;&#x2F;code&gt; interface.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Smart contracts implementing the ERC-1155 standard MUST implement the ERC-165 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function and MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0xd9b67a26&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.5.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-1155 Multi Token Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1155&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: The ERC-165 identifier for this interface is 0xd9b67a26.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_operator` argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_from` argument MUST be the address of the holder whose balance is decreased.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_to` argument MUST be the address of the recipient whose balance is increased.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_id` argument MUST be the token type being transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        When minting&#x2F;creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        When burning&#x2F;destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferSingle&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_operator` argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_from` argument MUST be the address of the holder whose balance is decreased.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_to` argument MUST be the address of the recipient whose balance is increased.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_ids` argument MUST be the list of tokens being transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        When minting&#x2F;creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        When burning&#x2F;destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransferBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when approval for a second party&#x2F;operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled).        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit when the URI is updated for a token ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        URIs are defined in RFC 3986.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The URI MUST point to a JSON file that conforms to the &amp;quot;ERC-1155 Metadata URI JSON Schema&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; URI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Caller must be approved to manage the tokens being transferred out of the `_from` account (see &amp;quot;Approval&amp;quot; section of the standard).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert if `_to` is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert if balance of holder for token `_id` is lower than the `_value` sent.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert on any other error.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST emit the `TransferSingle` event to reflect the balance change (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size &amp;gt; 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Source address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Target address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      ID of the token type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   Transfer amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Caller must be approved to manage the tokens being transferred out of the `_from` account (see &amp;quot;Approval&amp;quot; section of the standard).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert if `_to` is the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert if length of `_ids` is not the same as length of `_values`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST revert on any other error.        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        Balance changes and events MUST follow the ordering of the arrays (_ids[0]&#x2F;_values[0] before _ids[1]&#x2F;_values[1], etc).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size &amp;gt; 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see &amp;quot;Safe Transfer Rules&amp;quot; section of the standard).                      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Source address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Target address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     IDs of each token type (order and length must match _values array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Transfer amounts per token type (order and length must match _ids array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeBatchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the balance of an account&amp;#39;s tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address of the token holder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     ID of the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;        The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _owner&amp;#39;s balance of the token type requested&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the balance of multiple account&#x2F;token pairs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owners&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The addresses of the token holders&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    ID of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;        The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; _owner&amp;#39;s balance of the token types requested (i.e. balance for each (owner, id) pair)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOfBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owners&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enable or disable approval for a third party (&amp;quot;operator&amp;quot;) to manage all of the caller&amp;#39;s tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MUST emit the ApprovalForAll event on success.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Address to add to the set of authorized operators&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  True if the operator is approved, false to revoke approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Queries the approval status of an operator for a given owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The owner of the tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Address of authorized operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;           True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if the operator is approved, false if not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-1155-token-receiver&quot;&gt;ERC-1155 Token Receiver&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Smart contracts MUST implement all of the functions in the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface to accept transfers. See &quot;Safe Transfer Rules&quot; for further detail.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Smart contracts MUST implement the ERC-165 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function and signify support for the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface to accept transfers. See &quot;ERC1155TokenReceiver ERC-165 rules&quot; for further detail.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.5.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: The ERC-165 identifier for this interface is 0x4e2312e0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155TokenReceiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the receipt of a single ERC1155 token type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        This function MUST return `bytes4(keccak256(&amp;quot;onERC1155Received(address,address,uint256,uint256,bytes)&amp;quot;))` (i.e. 0xf23a6e61) if it accepts the transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        This function MUST revert if it rejects the transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address which initiated the transfer (i.e. msg.sender)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The address which previously owned the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The ID of the token being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     The amount of tokens being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           `bytes4(keccak256(&amp;quot;onERC1155Received(address,address,uint256,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onERC1155Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the receipt of multiple ERC1155 token types.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        This function MUST return `bytes4(keccak256(&amp;quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&amp;quot;))` (i.e. 0xbc197c81) if it accepts the transfer(s).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        This function MUST revert if it rejects the transfer(s).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The address which initiated the batch transfer (i.e. msg.sender)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      The address which previously owned the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;       An array containing ids of each token being transferred (order and length must match _values array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    An array containing amounts of each token being transferred (order and length must match _ids array)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;           `bytes4(keccak256(&amp;quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onERC1155BatchReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _values&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;safe-transfer-rules&quot;&gt;Safe Transfer Rules&lt;&#x2F;h3&gt;
&lt;p&gt;To be more explicit about how the standard &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; and &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; functions MUST operate with respect to the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook functions, a list of scenarios and rules follows.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;scenarios&quot;&gt;Scenarios&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#1 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The recipient is not a contract.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; MUST NOT be called on an EOA (Externally Owned Account).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#2 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The transaction is not a mint&#x2F;transfer of a token.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; MUST NOT be called outside of a mint or transfer process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#3 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The receiver does not implement the necessary &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface function(s).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The transfer MUST be reverted with the one caveat below.
&lt;ul&gt;
&lt;li&gt;If the token(s) being sent are part of a hybrid implementation of another standard, that particular standard&#x27;s rules on sending to a contract MAY now be followed instead. See &quot;Backwards Compatibility&quot; section.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#4 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The receiver implements the necessary &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface function(s) but returns an unknown value.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The transfer MUST be reverted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#5 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The receiver implements the necessary &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface function(s) but throws an error.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The transfer MUST be reverted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#6 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The receiver implements the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface and is the recipient of one and only one balance change (e.g. &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; called).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The balances for the transfer MUST have been updated before the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook is called on a recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;The transfer event MUST have been emitted to reflect the balance changes before the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook is called on the recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;One of &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; MUST be called on the recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; hook SHOULD be called on the recipient contract and its rules followed.
&lt;ul&gt;
&lt;li&gt;See &quot;onERC1155Received rules&quot; for further rules that MUST be followed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; hook MAY be called on the recipient contract and its rules followed.
&lt;ul&gt;
&lt;li&gt;See &quot;onERC1155BatchReceived rules&quot; for further rules that MUST be followed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#7 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; The receiver implements the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface and is the recipient of more than one balance change (e.g. &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; called).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;All balance transfers that are referenced in a call to an &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook MUST be updated before the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook is called on the recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;All transfer events MUST have been emitted to reflect current balance changes before an &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook is called on the recipient contract.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; MUST be called on the recipient as many times as necessary such that every balance change for the recipient in the scenario is accounted for.
&lt;ul&gt;
&lt;li&gt;The return magic value for every hook call MUST be checked and acted upon as per &quot;onERC1155Received rules&quot; and &quot;onERC1155BatchReceived rules&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; hook SHOULD be called on the recipient contract and its rules followed.
&lt;ul&gt;
&lt;li&gt;See &quot;onERC1155BatchReceived rules&quot; for further rules that MUST be followed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; hook MAY be called on the recipient contract and its rules followed.
&lt;ul&gt;
&lt;li&gt;See &quot;onERC1155Received rules&quot; for further rules that MUST be followed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#8 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; You are the creator of a contract that implements the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface and you forward the token(s) onto another address in one or both of &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Forwarding should be considered acceptance and then initiating a new &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; in a new context.
&lt;ul&gt;
&lt;li&gt;The prescribed keccak256 acceptance value magic for the receiver hook being called MUST be returned after forwarding is successful.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; argument MAY be re-purposed for the new context.&lt;&#x2F;li&gt;
&lt;li&gt;If forwarding fails the transaction MAY be reverted.
&lt;ul&gt;
&lt;li&gt;If the contract logic wishes to keep the ownership of the token(s) itself in this case it MAY do so.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scenario#9 :&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; You are transferring tokens via a non-standard API call i.e. an implementation specific API and NOT &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In this scenario all balance updates and events output rules are the same as if a standard transfer function had been called.
&lt;ul&gt;
&lt;li&gt;i.e. an external viewer MUST still be able to query the balance via a standard function and it MUST be identical to the balance as determined by &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; and &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; events alone.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If the receiver is a contract the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hooks still need to be called on it and the return values respected the same as if a standard transfer function had been called.
&lt;ul&gt;
&lt;li&gt;However while the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; functions MUST revert if a receiving contract does not implement the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface, a non-standard function MAY proceed with the transfer.&lt;&#x2F;li&gt;
&lt;li&gt;See &quot;Implementation specific transfer API rules&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;rules&quot;&gt;Rules&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;safeTransferFrom rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Caller must be approved to manage the tokens being transferred out of the &lt;code&gt;_from&lt;&#x2F;code&gt; account (see &quot;Approval&quot; section).&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_to&lt;&#x2F;code&gt; is the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if balance of holder for token &lt;code&gt;_id&lt;&#x2F;code&gt; is lower than the &lt;code&gt;_value&lt;&#x2F;code&gt; sent to the recipient.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert on any other error.&lt;&#x2F;li&gt;
&lt;li&gt;MUST emit the &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; event to reflect the balance change (see &quot;TransferSingle and TransferBatch event rules&quot; section).&lt;&#x2F;li&gt;
&lt;li&gt;After the above conditions are met, this function MUST check if &lt;code&gt;_to&lt;&#x2F;code&gt; is a smart contract (e.g. code size &amp;gt; 0). If so, it MUST call &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; on &lt;code&gt;_to&lt;&#x2F;code&gt; and act appropriately (see &quot;onERC1155Received rules&quot; section).
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; argument provided by the sender for the transfer MUST be passed with its contents unaltered to the &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; hook function via its &lt;code&gt;_data&lt;&#x2F;code&gt; argument.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;safeBatchTransferFrom rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Caller must be approved to manage all the tokens being transferred out of the &lt;code&gt;_from&lt;&#x2F;code&gt; account (see &quot;Approval&quot; section).&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if &lt;code&gt;_to&lt;&#x2F;code&gt; is the zero address.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if length of &lt;code&gt;_ids&lt;&#x2F;code&gt; is not the same as length of &lt;code&gt;_values&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert if any of the balance(s) of the holder(s) for token(s) in &lt;code&gt;_ids&lt;&#x2F;code&gt; is lower than the respective amount(s) in &lt;code&gt;_values&lt;&#x2F;code&gt; sent to the recipient.&lt;&#x2F;li&gt;
&lt;li&gt;MUST revert on any other error.&lt;&#x2F;li&gt;
&lt;li&gt;MUST emit &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; or &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; event(s) such that all the balance changes are reflected (see &quot;TransferSingle and TransferBatch event rules&quot; section).&lt;&#x2F;li&gt;
&lt;li&gt;The balance changes and events MUST occur in the array order they were submitted (_ids[0]&#x2F;_values[0] before _ids[1]&#x2F;_values[1], etc).&lt;&#x2F;li&gt;
&lt;li&gt;After the above conditions are met, this function MUST check if &lt;code&gt;_to&lt;&#x2F;code&gt; is a smart contract (e.g. code size &amp;gt; 0). If so, it MUST call &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; on &lt;code&gt;_to&lt;&#x2F;code&gt; and act appropriately (see &quot;onERC1155Received and onERC1155BatchReceived rules&quot; section).
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; argument provided by the sender for the transfer MUST be passed with its contents unaltered to the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook function(s) via their &lt;code&gt;_data&lt;&#x2F;code&gt; argument.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;TransferSingle and TransferBatch event rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TransferSingle&lt;&#x2F;code&gt; SHOULD be used to indicate a single balance transfer has occurred between a &lt;code&gt;_from&lt;&#x2F;code&gt; and &lt;code&gt;_to&lt;&#x2F;code&gt; pair.
&lt;ul&gt;
&lt;li&gt;It MAY be emitted multiple times to indicate multiple balance changes in the transaction, but note that &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; is designed for this to reduce gas consumption.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_operator&lt;&#x2F;code&gt; argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be the address of the holder whose balance is decreased.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_to&lt;&#x2F;code&gt; argument MUST be the address of the recipient whose balance is increased.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_id&lt;&#x2F;code&gt; argument MUST be the token type being transferred.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_value&lt;&#x2F;code&gt; argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.&lt;&#x2F;li&gt;
&lt;li&gt;When minting&#x2F;creating tokens, the &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address). See &quot;Minting&#x2F;creating and burning&#x2F;destroying rules&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;When burning&#x2F;destroying tokens, the &lt;code&gt;_to&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address). See &quot;Minting&#x2F;creating and burning&#x2F;destroying rules&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TransferBatch&lt;&#x2F;code&gt; SHOULD be used to indicate multiple balance transfers have occurred between a &lt;code&gt;_from&lt;&#x2F;code&gt; and &lt;code&gt;_to&lt;&#x2F;code&gt; pair.
&lt;ul&gt;
&lt;li&gt;It MAY be emitted with a single element in the list to indicate a singular balance change in the transaction, but note that &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; is designed for this to reduce gas consumption.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_operator&lt;&#x2F;code&gt; argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be the address of the holder whose balance is decreased for each entry pair in &lt;code&gt;_ids&lt;&#x2F;code&gt; and &lt;code&gt;_values&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_to&lt;&#x2F;code&gt; argument MUST be the address of the recipient whose balance is increased for each entry pair in &lt;code&gt;_ids&lt;&#x2F;code&gt; and &lt;code&gt;_values&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_ids&lt;&#x2F;code&gt; array argument MUST contain the ids of the tokens being transferred.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;_values&lt;&#x2F;code&gt; array argument MUST contain the number of token to be transferred for each corresponding entry in &lt;code&gt;_ids&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;_ids&lt;&#x2F;code&gt; and &lt;code&gt;_values&lt;&#x2F;code&gt; MUST have the same length.&lt;&#x2F;li&gt;
&lt;li&gt;When minting&#x2F;creating tokens, the &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address). See &quot;Minting&#x2F;creating and burning&#x2F;destroying rules&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;When burning&#x2F;destroying tokens, the &lt;code&gt;_to&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address). See &quot;Minting&#x2F;creating and burning&#x2F;destroying rules&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The total value transferred from address &lt;code&gt;0x0&lt;&#x2F;code&gt; minus the total value transferred to &lt;code&gt;0x0&lt;&#x2F;code&gt; observed via the &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; and &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; events MAY be used by clients and exchanges to determine the &quot;circulating supply&quot; for a given token ID.&lt;&#x2F;li&gt;
&lt;li&gt;To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; event from &lt;code&gt;0x0&lt;&#x2F;code&gt; to &lt;code&gt;0x0&lt;&#x2F;code&gt;, with the token creator as &lt;code&gt;_operator&lt;&#x2F;code&gt;, and a &lt;code&gt;_value&lt;&#x2F;code&gt; of 0.&lt;&#x2F;li&gt;
&lt;li&gt;All &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; and &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; events MUST be emitted to reflect all the balance changes that have occurred before any call(s) to &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt;.
&lt;ul&gt;
&lt;li&gt;To make sure event order is correct in the case of valid re-entry (e.g. if a receiver contract forwards tokens on receipt) state balance and events balance MUST match before calling an external contract.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;onERC1155Received rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_operator&lt;&#x2F;code&gt; argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be the address of the holder whose balance is decreased.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_from&lt;&#x2F;code&gt; MUST be 0x0 for a mint.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_id&lt;&#x2F;code&gt; argument MUST be the token type being transferred.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_value&lt;&#x2F;code&gt; argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; argument MUST contain the information provided by the sender for the transfer with its contents unaltered.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;i.e. it MUST pass on the unaltered &lt;code&gt;_data&lt;&#x2F;code&gt; argument sent via the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; call for this transfer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The recipient contract MAY accept an increase of its balance by returning the acceptance magic value &lt;code&gt;bytes4(keccak256(&quot;onERC1155Received(address,address,uint256,uint256,bytes)&quot;))&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the return value is &lt;code&gt;bytes4(keccak256(&quot;onERC1155Received(address,address,uint256,uint256,bytes)&quot;))&lt;&#x2F;code&gt; the transfer MUST be completed or MUST revert if any other conditions are not met for success.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The recipient contract MAY reject an increase of its balance by calling revert.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the recipient contract throws&#x2F;reverts the transaction MUST be reverted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the return value is anything other than &lt;code&gt;bytes4(keccak256(&quot;onERC1155Received(address,address,uint256,uint256,bytes)&quot;))&lt;&#x2F;code&gt; the transaction MUST be reverted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; (and&#x2F;or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt;) MAY be called multiple times in a single transaction and the following requirements must be met:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;All callbacks represent mutually exclusive balance changes.&lt;&#x2F;li&gt;
&lt;li&gt;The set of all calls to &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; describes all balance changes that occurred during the transaction in the order submitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A contract MAY skip calling the &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; hook function if the transfer operation is transferring the token to itself.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;onERC1155BatchReceived rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_operator&lt;&#x2F;code&gt; argument MUST be the address of an account&#x2F;contract that is approved to make the transfer (SHOULD be msg.sender).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be the address of the holder whose balance is decreased.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_from&lt;&#x2F;code&gt; MUST be 0x0 for a mint.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_ids&lt;&#x2F;code&gt; argument MUST be the list of tokens being transferred.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_values&lt;&#x2F;code&gt; argument MUST be the list of number of tokens (matching the list and order of tokens specified in &lt;code&gt;_ids&lt;&#x2F;code&gt;) the holder balance is decreased by and match what the recipient balance is increased by.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;_data&lt;&#x2F;code&gt; argument MUST contain the information provided by the sender for the transfer with its contents unaltered.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;i.e. it MUST pass on the unaltered &lt;code&gt;_data&lt;&#x2F;code&gt; argument sent via the &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; call for this transfer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The recipient contract MAY accept an increase of its balance by returning the acceptance magic value &lt;code&gt;bytes4(keccak256(&quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&quot;))&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the return value is &lt;code&gt;bytes4(keccak256(&quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&quot;))&lt;&#x2F;code&gt; the transfer MUST be completed or MUST revert if any other conditions are not met for success.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The recipient contract MAY reject an increase of its balance by calling revert.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the recipient contract throws&#x2F;reverts the transaction MUST be reverted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the return value is anything other than &lt;code&gt;bytes4(keccak256(&quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&quot;))&lt;&#x2F;code&gt; the transaction MUST be reverted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; (and&#x2F;or &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt;) MAY be called multiple times in a single transaction and the following requirements must be met:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;All callbacks represent mutually exclusive balance changes.&lt;&#x2F;li&gt;
&lt;li&gt;The set of all calls to &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; describes all balance changes that occurred during the transaction in the order submitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A contract MAY skip calling the &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; hook function if the transfer operation is transferring the token(s) to itself.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;ERC1155TokenReceiver ERC-165 rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The implementation of the ERC-165 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function SHOULD be as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt;  interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-165 support (i.e. `bytes4(keccak256(&amp;#39;supportsInterface(bytes4)&amp;#39;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x4e2312e0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;      &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-1155 `ERC1155TokenReceiver` support (i.e. `bytes4(keccak256(&amp;quot;onERC1155Received(address,address,uint256,uint256,bytes)&amp;quot;)) ^ bytes4(keccak256(&amp;quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&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;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The implementation MAY differ from the above but:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument. This signifies ERC-165 support.&lt;&#x2F;li&gt;
&lt;li&gt;It MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0x4e2312e0&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument. This signifies ERC-1155 &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; support.&lt;&#x2F;li&gt;
&lt;li&gt;It MUST NOT consume more than 10,000 gas.
&lt;ul&gt;
&lt;li&gt;This keeps it below the ERC-165 requirement of 30,000 gas, reduces the gas reserve needs and minimises possible side-effects of gas exhaustion during the call.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Implementation specific transfer API rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If an implementation specific API function is used to transfer ERC-1155 token(s) to a contract, the &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; (as appropriate) rules MUST still be followed if the receiver implements the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface. If it does not the non-standard implementation SHOULD revert but MAY proceed.&lt;&#x2F;li&gt;
&lt;li&gt;An example:
&lt;ol&gt;
&lt;li&gt;An approved user calls a function such as &lt;code&gt;function myTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values);&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; updates the balances for &lt;code&gt;_from&lt;&#x2F;code&gt; and &lt;code&gt;_to&lt;&#x2F;code&gt; addresses for all &lt;code&gt;_ids&lt;&#x2F;code&gt; and &lt;code&gt;_values&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; emits &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; with the details of what was transferred from address &lt;code&gt;_from&lt;&#x2F;code&gt; to address &lt;code&gt;_to&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; checks if &lt;code&gt;_to&lt;&#x2F;code&gt; is a contract address and determines that it is so (if not, then the transfer can be considered successful).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; calls &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; on &lt;code&gt;_to&lt;&#x2F;code&gt; and it reverts or returns an unknown value (if it had returned &lt;code&gt;bytes4(keccak256(&quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&quot;))&lt;&#x2F;code&gt; the transfer can be considered successful).&lt;&#x2F;li&gt;
&lt;li&gt;At this point &lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; SHOULD revert the transaction immediately as receipt of the token(s) was not explicitly accepted by the &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;li&gt;If however &lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; wishes to continue it MUST call &lt;code&gt;supportsInterface(0x4e2312e0)&lt;&#x2F;code&gt; on &lt;code&gt;_to&lt;&#x2F;code&gt; and if it returns the constant value &lt;code&gt;true&lt;&#x2F;code&gt; the transaction MUST be reverted, as it is now known to be a valid receiver and the previous acceptance step failed.
&lt;ul&gt;
&lt;li&gt;NOTE: You could have called &lt;code&gt;supportsInterface(0x4e2312e0)&lt;&#x2F;code&gt; at a previous step if you wanted to gather and act upon that information earlier, such as in a hybrid standards scenario.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If the above call to &lt;code&gt;supportsInterface(0x4e2312e0)&lt;&#x2F;code&gt; on &lt;code&gt;_to&lt;&#x2F;code&gt; reverts or returns a value other than the constant value &lt;code&gt;true&lt;&#x2F;code&gt; the &lt;code&gt;myTransferFrom&lt;&#x2F;code&gt; function MAY consider this transfer successful.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NOTE&lt;&#x2F;strong&gt;: this MAY result in unrecoverable tokens if sent to an address that does not expect to receive ERC-1155 tokens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The above example is not exhaustive but illustrates the major points (and shows that most are shared with &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; and &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt;):
&lt;ul&gt;
&lt;li&gt;Balances that are updated MUST have equivalent transfer events emitted.&lt;&#x2F;li&gt;
&lt;li&gt;A receiver address has to be checked if it is a contract and if so relevant &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook function(s) have to be called on it.&lt;&#x2F;li&gt;
&lt;li&gt;Balances (and events associated) that are referenced in a call to an &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook MUST be updated (and emitted) before the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook is called.&lt;&#x2F;li&gt;
&lt;li&gt;The return values of the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook functions that are called MUST be respected if they are implemented.&lt;&#x2F;li&gt;
&lt;li&gt;Only non-standard transfer functions MAY allow tokens to be sent to a recipient contract that does NOT implement the necessary &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook functions. &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; and &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; MUST revert in that case (unless it is a hybrid standards implementation see &quot;Backwards Compatibility&quot;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Minting&#x2F;creating and burning&#x2F;destroying rules:&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A mint&#x2F;create operation is essentially a specialized transfer and MUST follow these rules:
&lt;ul&gt;
&lt;li&gt;To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; event from &lt;code&gt;0x0&lt;&#x2F;code&gt; to &lt;code&gt;0x0&lt;&#x2F;code&gt;, with the token creator as &lt;code&gt;_operator&lt;&#x2F;code&gt;, and a &lt;code&gt;_value&lt;&#x2F;code&gt; of 0.&lt;&#x2F;li&gt;
&lt;li&gt;The &quot;TransferSingle and TransferBatch event rules&quot; MUST be followed as appropriate for the mint(s) (i.e. singles or batches) however the &lt;code&gt;_from&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address) to flag the transfer as a mint to contract observers.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NOTE:&lt;&#x2F;strong&gt; This includes tokens that are given an initial balance in the contract. The balance of the contract MUST also be able to be determined by events alone meaning initial contract balances (for eg. in construction) MUST emit events to reflect those balances too.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A burn&#x2F;destroy operation is essentially a specialized transfer and MUST follow these rules:
&lt;ul&gt;
&lt;li&gt;The &quot;TransferSingle and TransferBatch event rules&quot; MUST be followed as appropriate for the burn(s) (i.e. singles or batches) however the &lt;code&gt;_to&lt;&#x2F;code&gt; argument MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; (i.e. zero address) to flag the transfer as a burn to contract observers.&lt;&#x2F;li&gt;
&lt;li&gt;When burning&#x2F;destroying you do not have to actually transfer to &lt;code&gt;0x0&lt;&#x2F;code&gt; (that is impl specific), only the &lt;code&gt;_to&lt;&#x2F;code&gt; argument in the event MUST be set to &lt;code&gt;0x0&lt;&#x2F;code&gt; as above.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The total value transferred from address &lt;code&gt;0x0&lt;&#x2F;code&gt; minus the total value transferred to &lt;code&gt;0x0&lt;&#x2F;code&gt; observed via the &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; and &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; events MAY be used by clients and exchanges to determine the &quot;circulating supply&quot; for a given token ID.&lt;&#x2F;li&gt;
&lt;li&gt;As mentioned above mint&#x2F;create and burn&#x2F;destroy operations are specialized transfers and so will likely be accomplished with custom transfer functions rather than &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; or &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt;. If so the &quot;Implementation specific transfer API rules&quot; section would be appropriate.
&lt;ul&gt;
&lt;li&gt;Even in a non-safe API and&#x2F;or hybrid standards case the above event rules MUST still be adhered to when minting&#x2F;creating or burning&#x2F;destroying.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A contract MAY skip calling the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; hook function(s) if the mint operation is transferring the token(s) to itself. In all other cases the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; rules MUST be followed as appropriate for the implementation (i.e. safe, custom and&#x2F;or hybrid).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;a-solidity-example-of-the-keccak256-generated-constants-for-the-various-magic-values-these-may-be-used-by-implementation&quot;&gt;A solidity example of the keccak256 generated constants for the various magic values (these MAY be used by implementation):&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; ERC1155_ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xd9b67a26&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-165 identifier for the main token standard.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; ERC1155_ERC165_TOKENRECEIVER &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x4e2312e0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-165 identifier for the `ERC1155TokenReceiver` support (i.e. `bytes4(keccak256(&amp;quot;onERC1155Received(address,address,uint256,uint256,bytes)&amp;quot;)) ^ bytes4(keccak256(&amp;quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&amp;quot;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; ERC1155_ACCEPTED &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xf23a6e61&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return value from `onERC1155Received` call if a contract accepts receipt (i.e `bytes4(keccak256(&amp;quot;onERC1155Received(address,address,uint256,uint256,bytes)&amp;quot;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; ERC1155_BATCH_ACCEPTED &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xbc197c81&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Return value from `onERC1155BatchReceived` call if a contract accepts receipt (i.e `bytes4(keccak256(&amp;quot;onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)&amp;quot;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;metadata&quot;&gt;Metadata&lt;&#x2F;h3&gt;
&lt;p&gt;The URI value allows for ID substitution by clients. If the string &lt;code&gt;{id}&lt;&#x2F;code&gt; exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form. This allows for a large number of tokens to use the same on-chain string by defining a URI once, for that large number of tokens.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The string format of the substituted hexadecimal ID MUST be lowercase alphanumeric: &lt;code&gt;[0-9a-f]&lt;&#x2F;code&gt; with no 0x prefix.&lt;&#x2F;li&gt;
&lt;li&gt;The string format of the substituted hexadecimal ID MUST be leading zero padded to 64 hex characters length if necessary.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example of such a URI: &lt;code&gt;https:&#x2F;&#x2F;token-cdn-domain&#x2F;{id}.json&lt;&#x2F;code&gt; would be replaced with &lt;code&gt;https:&#x2F;&#x2F;token-cdn-domain&#x2F;000000000000000000000000000000000000000000000000000000000004cce0.json&lt;&#x2F;code&gt; if the client is referring to token ID 314592&#x2F;0x4CCE0.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;metadata-extensions&quot;&gt;Metadata Extensions&lt;&#x2F;h4&gt;
&lt;p&gt;The optional &lt;code&gt;ERC1155Metadata_URI&lt;&#x2F;code&gt; extension can be identified with the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165 Standard Interface Detection&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the optional &lt;code&gt;ERC1155Metadata_URI&lt;&#x2F;code&gt; extension is included:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The ERC-165 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function MUST return the constant value &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;0x0e89341c&lt;&#x2F;code&gt; is passed through the &lt;code&gt;interfaceID&lt;&#x2F;code&gt; argument.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Changes&lt;&#x2F;em&gt; to the URI MUST emit the &lt;code&gt;URI&lt;&#x2F;code&gt; event if the change can be expressed with an event (i.e. it isn&#x27;t dynamic&#x2F;programmatic).
&lt;ul&gt;
&lt;li&gt;An implementation MAY emit the &lt;code&gt;URI&lt;&#x2F;code&gt; event during a mint operation but it is NOT mandatory. An observer MAY fetch the metadata uri at mint time from the &lt;code&gt;uri&lt;&#x2F;code&gt; function if it was not emitted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;uri&lt;&#x2F;code&gt; function SHOULD be used to retrieve values if no event was emitted.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;uri&lt;&#x2F;code&gt; function MUST return the same value as the latest event for an &lt;code&gt;_id&lt;&#x2F;code&gt; if it was emitted.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;uri&lt;&#x2F;code&gt; function MUST NOT be used to check for the existence of a token as it is possible for an implementation to return a valid string even if the token does not exist.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.5.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: The ERC-165 identifier for this interface is 0x0e89341c.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155Metadata_URI&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A distinct Uniform Resource Identifier (URI) for a given token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; URIs are defined in RFC 3986.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        The URI MUST point to a JSON file that conforms to the &amp;quot;ERC-1155 Metadata URI JSON Schema&amp;quot;.        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; URI&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; uri&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _id&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;erc-1155-metadata-uri-json-schema&quot;&gt;ERC-1155 Metadata URI JSON Schema&lt;&#x2F;h4&gt;
&lt;p&gt;This JSON schema is loosely based on the &quot;ERC721 Metadata JSON Schema&quot;, but includes optional formatting to allow for ID substitution by clients. If the string &lt;code&gt;{id}&lt;&#x2F;code&gt; exists in any JSON value, it MUST be replaced with the actual token ID, by all client software that follows this standard.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The string format of the substituted hexadecimal ID MUST be lowercase alphanumeric: &lt;code&gt;[0-9a-f]&lt;&#x2F;code&gt; with no 0x prefix.&lt;&#x2F;li&gt;
&lt;li&gt;The string format of the substituted hexadecimal ID MUST be leading zero padded to 64 hex characters length if necessary.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Token Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;decimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The number of decimal places that the token amount should display - e.g. 18, means to divide the token amount by 1000000000000000000 to get its user representation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this token represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Arbitrary properties. Values may be strings, numbers, object or arrays.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;An example of an ERC-1155 Metadata JSON file follows. The properties array proposes some SUGGESTED formatting for token-specific display properties and metadata.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Lorem ipsum...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s3.amazonaws.com&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;your-bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;images&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{id}.png&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;simple_property&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;example value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;rich_property&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;123&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;display_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;123 Example Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;emphasis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;css&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;				&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;color&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;#ffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;				&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;font-weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bold&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;				&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;text-decoration&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;underline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;array_property&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;			&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;emphasis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;h5 id=&quot;localization&quot;&gt;Localization&lt;&#x2F;h5&gt;
&lt;p&gt;Metadata localization should be standardized to increase presentation uniformity across all languages. As such, a simple overlay method is proposed to enable localization. If the metadata JSON file contains a &lt;code&gt;localization&lt;&#x2F;code&gt; attribute, its content MAY be used to provide localized values for fields that need it. The &lt;code&gt;localization&lt;&#x2F;code&gt; attribute should be a sub-object with three attributes: &lt;code&gt;uri&lt;&#x2F;code&gt;, &lt;code&gt;default&lt;&#x2F;code&gt; and &lt;code&gt;locales&lt;&#x2F;code&gt;. If the string &lt;code&gt;{locale}&lt;&#x2F;code&gt; exists in any URI, it MUST be replaced with the chosen locale by all client software.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;json-schema&quot;&gt;JSON Schema&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Token Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;decimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The number of decimal places that the token amount should display - e.g. 18, means to divide the token amount by 1000000000000000000 to get its user representation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this token represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this token represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Arbitrary properties. Values may be strings, numbers, object or arrays.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;localization&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;required&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;locales&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The URI pattern to fetch localized data from. This URI should contain the substring `{locale}` which will be replaced with the appropriate locale value before sending the request.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The locale of the default data within the base JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;locales&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The list of locales for which data is available. These locales should conform to those defined in the Unicode Common Locale Data Repository (http:&#x2F;&#x2F;cldr.unicode.org&#x2F;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;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;h5 id=&quot;localized-sample&quot;&gt;Localized Sample&lt;&#x2F;h5&gt;
&lt;p&gt;Base URI:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Advertising Space&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Each token represents a unique Ad space in the city.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;localization&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uri&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ipfs:&#x2F;&#x2F;QmWS1VAdMD353A6SDk9wNyvkT14kyCiZrNDYAad4w1tKqT&#x2F;{locale}.json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;en&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;locales&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;en&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;es&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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;es.json:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Espacio Publicitario&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Cada token representa un espacio publicitario único en la ciudad.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;fr.json:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Espace Publicitaire&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Chaque jeton représente un espace publicitaire unique dans la ville.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;h3 id=&quot;approval&quot;&gt;Approval&lt;&#x2F;h3&gt;
&lt;p&gt;The function &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; allows an operator to manage one&#x27;s entire set of tokens on behalf of the approver. To permit approval of a subset of token IDs, an interface such as &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1761&#x2F;&quot;&gt;ERC-1761 Scoped Approval Interface&lt;&#x2F;a&gt; is suggested.
The counterpart &lt;code&gt;isApprovedForAll&lt;&#x2F;code&gt; provides introspection into any status set by &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An owner SHOULD be assumed to always be able to operate on their own tokens regardless of approval status, so should SHOULD NOT have to call &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; to approve themselves as an operator before they can operate on them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;metadata-choices&quot;&gt;Metadata Choices&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;symbol&lt;&#x2F;code&gt; function (found in the ERC-20 and ERC-721 standards) was not included as we do not believe this is a globally useful piece of data to identify a generic virtual item &#x2F; asset and are also prone to collisions. Short-hand symbols are used in tickers and currency trading, but they aren&#x27;t as useful outside of that space.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;name&lt;&#x2F;code&gt; function (for human-readable asset names, on-chain) was removed from the standard to allow the Metadata JSON to be the definitive asset name and reduce duplication of data. This also allows localization for names, which would otherwise be prohibitively expensive if each language string was stored on-chain, not to mention bloating the standard interface. While this decision may add a small burden on implementers to host a JSON file containing metadata, we believe any serious implementation of ERC-1155 will already utilize JSON Metadata.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;upgrades&quot;&gt;Upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;The requirement to emit &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; or &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; on balance change implies that a valid implementation of ERC-1155 redeploying to a new contract address MUST emit events from the new contract address to replicate the deprecated contract final state. It is valid to only emit a minimal number of events to reflect only the final balance and omit all the transactions that led to that state. The event emit requirement is to ensure that the current state of the contract can always be traced only through events. To alleviate the need to emit events when changing contract address, consider using the proxy pattern, such as described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2535&#x2F;&quot;&gt;EIP-2535&lt;&#x2F;a&gt;. This will also have the added benefit of providing a stable contract address for users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-decision-supporting-non-batch&quot;&gt;Design decision: Supporting non-batch&lt;&#x2F;h3&gt;
&lt;p&gt;The standard supports &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; and &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; functions because they are significantly cheaper for single token-type transfers, which is arguably a common use case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-decision-safe-transfers-only&quot;&gt;Design decision: Safe transfers only&lt;&#x2F;h3&gt;
&lt;p&gt;The standard only supports safe-style transfers, making it possible for receiver contracts to depend on &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; function to be always called at the end of a transfer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;guaranteed-log-trace&quot;&gt;Guaranteed log trace&lt;&#x2F;h3&gt;
&lt;p&gt;As the Ethereum ecosystem continues to grow, many dapps are relying on traditional databases and explorer API services to retrieve and categorize data. The ERC-1155 standard guarantees that event logs emitted by the smart contract will provide enough data to create an accurate record of all current token balances. A database or explorer may listen to events and be able to provide indexed and categorized searches of every ERC-1155 token in the contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;approval-1&quot;&gt;Approval&lt;&#x2F;h3&gt;
&lt;p&gt;The function &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; allows an operator to manage one&#x27;s entire set of tokens on behalf of the approver. It enables frictionless interaction with exchange and trade contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Restricting approval to a certain set of token IDs, quantities or other rules MAY be done with an additional interface or an external contract. The rationale is to keep the ERC-1155 standard as generic as possible for all use-cases without imposing a specific approval scheme on implementations that may not need it. Standard token approval interfaces can be used, such as the suggested &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1761&#x2F;&quot;&gt;ERC-1761 Scoped Approval Interface&lt;&#x2F;a&gt; which is compatible with ERC-1155.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There have been requirements during the design discussions to have this standard be compatible with existing standards when sending to contract addresses, specifically ERC-721 at time of writing.
To cater for this scenario, there is some leeway with the revert logic should a contract not implement the &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; as per &quot;Safe Transfer Rules&quot; section above, specifically &quot;Scenario#3 : The receiver does not implement the necessary &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; interface function(s)&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Hence in a hybrid ERC-1155 contract implementation an extra call MUST be made on the recipient contract and checked before any hook calls to &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; are made.
Order of operation MUST therefore be:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The implementation MUST call the function &lt;code&gt;supportsInterface(0x4e2312e0)&lt;&#x2F;code&gt; on the recipient contract, providing at least 10,000 gas.&lt;&#x2F;li&gt;
&lt;li&gt;If the function call succeeds and the return value is the constant value &lt;code&gt;true&lt;&#x2F;code&gt; the implementation proceeds as a regular ERC-1155 implementation, with the call(s) to the &lt;code&gt;onERC1155Received&lt;&#x2F;code&gt; or &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt; hooks and rules associated.&lt;&#x2F;li&gt;
&lt;li&gt;If the function call fails or the return value is NOT the constant value &lt;code&gt;true&lt;&#x2F;code&gt; the implementation can assume the recipient contract is not an &lt;code&gt;ERC1155TokenReceiver&lt;&#x2F;code&gt; and follow its other standard&#x27;s rules for transfers.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note that a pure implementation of a single standard is recommended&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; rather than a hybrid solution, but an example of a hybrid ERC-1155&#x2F;ERC-721 contract is linked in the references section under implementations.&lt;&#x2F;p&gt;
&lt;p&gt;An important consideration is that even if the tokens are sent with another standard&#x27;s rules the &lt;em&gt;&lt;strong&gt;ERC-1155 transfer events MUST still be emitted.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; This is so the balances can still be determined via events alone as per ERC-1155 standard rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;p&gt;This standard can be used to represent multiple token types for an entire domain. Both fungible and non-fungible tokens can be stored in the same smart-contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;batch-transfers&quot;&gt;Batch Transfers&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;safeBatchTransferFrom&lt;&#x2F;code&gt; function allows for batch transfers of multiple token IDs and values. The design of ERC-1155 makes batch transfers possible without the need for a wrapper contract, as with existing token standards. This reduces gas costs when more than one token type is included in a batch transfer, as compared to single transfers with multiple transactions.&lt;&#x2F;p&gt;
&lt;p&gt;Another advantage of standardized batch transfers is the ability for a smart contract to respond to the batch transfer in a single operation using &lt;code&gt;onERC1155BatchReceived&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is RECOMMENDED that clients and wallets sort the token IDs and associated values (in ascending order) when posting a batch transfer, as some ERC-1155 implementations offer significant gas cost savings when IDs are sorted. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;horizon-games&#x2F;multi-token-standard&quot;&gt;Horizon Games - Multi-Token Standard&lt;&#x2F;a&gt; &quot;packed balance&quot; implementation for an example of this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;batch-balance&quot;&gt;Batch Balance&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;balanceOfBatch&lt;&#x2F;code&gt; function allows clients to retrieve balances of multiple owners and token IDs with a single call.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enumerating-from-events&quot;&gt;Enumerating from events&lt;&#x2F;h3&gt;
&lt;p&gt;In order to keep storage requirements light for contracts implementing ERC-1155, enumeration (discovering the IDs and values of tokens) must be done using event logs. It is RECOMMENDED that clients such as exchanges and blockchain explorers maintain a local database containing the token ID, Supply, and URI at the minimum. This can be built from each TransferSingle, TransferBatch, and URI event, starting from the block the smart contract was deployed until the latest block.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-1155 contracts must therefore carefully emit &lt;code&gt;TransferSingle&lt;&#x2F;code&gt; or &lt;code&gt;TransferBatch&lt;&#x2F;code&gt; events in any instance where tokens are created, minted, transferred or destroyed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;non-fungible-tokens&quot;&gt;Non-Fungible Tokens&lt;&#x2F;h3&gt;
&lt;p&gt;The following strategies are examples of how you MAY mix fungible and non-fungible tokens together in the same contract. The standard does NOT mandate how an implementation must do this.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;split-id-bits&quot;&gt;Split ID bits&lt;&#x2F;h5&gt;
&lt;p&gt;The top 128 bits of the uint256 &lt;code&gt;_id&lt;&#x2F;code&gt; parameter in any ERC-1155 function MAY represent the base token ID, while the bottom 128 bits MAY represent the index of the non-fungible to make it unique.&lt;&#x2F;p&gt;
&lt;p&gt;Non-fungible tokens can be interacted with using an index based accessor into the contract&#x2F;token data set. Therefore to access a particular token set within a mixed data contract and a particular non-fungible within that set, &lt;code&gt;_id&lt;&#x2F;code&gt; could be passed as &lt;code&gt;&amp;lt;uint128: base token id&amp;gt;&amp;lt;uint128: index of non-fungible&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To identify a non-fungible set&#x2F;category as a whole (or a fungible) you COULD just pass in the base id via the &lt;code&gt;_id&lt;&#x2F;code&gt; argument as &lt;code&gt;&amp;lt;uint128: base token id&amp;gt;&amp;lt;uint128: zero&amp;gt;&lt;&#x2F;code&gt;. If your implementation uses this technique this naturally means the index of a non-fungible SHOULD be 1-based.&lt;&#x2F;p&gt;
&lt;p&gt;Inside the contract code the two pieces of data needed to access the individual non-fungible can be extracted with uint128(~0) and the same mask shifted by 128.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; baseTokenNFT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12345&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;uint128&lt;&#x2F;span&gt;&lt;span&gt; indexNFT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; baseTokenFT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54321&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 128&lt;&#x2F;span&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 class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; baseTokenNFT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get balance of the base token for non-fungible set 12345 (this MAY be used to get balance of the user for all of this token set if the implementation wishes as a convenience).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; baseTokenNFT &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; indexNFT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get balance of the token at index 50 for non-fungible set 12345 (should be 1 if user owns the individual non-fungible token or 0 if they do not).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; baseTokenFT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get balance of the fungible base token 54321.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that 128 is an arbitrary number, an implementation MAY choose how they would like this split to occur as suitable for their use case. An observer of the contract would simply see events showing balance transfers and mints happening and MAY track the balances using that information alone.
For an observer to be able to determine type (non-fungible or fungible) from an ID alone they would have to know the split ID bits format on a implementation by implementation basis.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;enjin&#x2F;erc-1155&quot;&gt;ERC-1155 Reference Implementation&lt;&#x2F;a&gt; is an example of the split ID bits strategy.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;natural-non-fungible-tokens&quot;&gt;Natural Non-Fungible tokens&lt;&#x2F;h5&gt;
&lt;p&gt;Another simple way to represent non-fungibles is to allow a maximum value of 1 for each non-fungible token. This would naturally mirror the real world, where unique items have a quantity of 1 and fungible items have a quantity greater than 1.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Standards&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721 Non-Fungible Token Standard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165 Standard Interface Detection&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1538&#x2F;&quot;&gt;ERC-1538 Transparent Contract Standard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;json-schema.org&#x2F;&quot;&gt;JSON Schema&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&quot;&gt;RFC 2119 Key words for use in RFCs to Indicate Requirement Levels&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Implementations&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;enjin&#x2F;erc-1155&quot;&gt;ERC-1155 Reference Implementation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;horizon-games&#x2F;multi-token-standard&quot;&gt;Horizon Games - Multi-Token Standard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;enjincoin.io&quot;&gt;Enjin Coin&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;enjin&quot;&gt;GitHub&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pixowl&#x2F;thesandbox-contracts&#x2F;tree&#x2F;master&#x2F;src&#x2F;Asset&quot;&gt;The Sandbox - Dual ERC-1155&#x2F;721 Contract&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Articles &amp;amp; Discussions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;1155&quot;&gt;GitHub - Original Discussion Thread&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.enjincoin.io&#x2F;erc-1155-the-crypto-item-standard-ac9cf1c5a226&quot;&gt;ERC-1155 - The Crypto Item Standard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;horizongames&#x2F;going-beyond-erc20-and-erc721-9acebd4ff6ef&quot;&gt;Here Be Dragons - Going Beyond ERC-20 and ERC-721 To Reduce Gas Cost by ~80%&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blockonomi.com&#x2F;erc1155-gaming-token&#x2F;&quot;&gt;Blockonomi - Ethereum ERC-1155 Token Perfect for Online Games, Possibly More&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blockgeeks.com&#x2F;erc-1155-token&#x2F;&quot;&gt;Beyond Gaming - Exploring the Utility of ERC-1155 Token Standard!&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;sandbox-game&#x2F;erc-1155-a-new-standard-for-the-sandbox-c95ee1e45072&quot;&gt;ERC-1155: A new standard for The Sandbox&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Transient storage opcodes</title>
        <published>2018-06-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alexey Akhunov</name><uri>https://github.com/AlexeyAkhunov</uri>
	</author>
	
	<author>
		<name>Moody Salem</name><uri>https://github.com/moodysalem</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1153/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-transient-storage-opcodes/553" />
        

        <id>https://wg-eips.ritovision.com/1153/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:1153"
            label="EIP-1153" />
        

        
        

        
        <summary type="html">Add opcodes for manipulating state that behaves almost identically to storage but is discarded after every transaction</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1153/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces transient storage opcodes, which manipulate state that behaves identically to storage, except that transient storage is discarded after every transaction, and &lt;code&gt;TSTORE&lt;&#x2F;code&gt; is not subject to the gas stipend check as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt;. In other words, the values of transient storage are never deserialized from storage or serialized to storage. Thus transient storage is cheaper since it never requires disk access. Transient storage is accessible to smart contracts via 2 new opcodes, &lt;code&gt;TLOAD&lt;&#x2F;code&gt; and &lt;code&gt;TSTORE&lt;&#x2F;code&gt;, where “T” stands for &quot;transient:&quot;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;TLOAD  (0x5c)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;TSTORE (0x5d)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Running a transaction in Ethereum can generate multiple nested frames of execution, each created by &lt;code&gt;CALL&lt;&#x2F;code&gt; (or similar) instructions. Contracts can be re-entered during the same transaction, in which case there are more than one frame belonging to one contract. Currently, these frames can communicate in two ways: via inputs&#x2F;outputs passed via &lt;code&gt;CALL&lt;&#x2F;code&gt; instructions, and via storage updates. If there is an intermediate frame belonging to another untrusted contract, communication via inputs&#x2F;outputs is not secure. Notable example is a reentrancy lock which cannot rely on the intermediate frame to pass through the state of the lock. Communication via storage (&lt;code&gt;SSTORE&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;SLOAD&lt;&#x2F;code&gt;) is costly. Transient storage is a dedicated and gas efficient solution to the problem of inter frame communication.&lt;&#x2F;p&gt;
&lt;p&gt;Storage refunds accumulated due to inter frame communication are also limited to 20% of gas spent by a transaction due to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3529&#x2F;&quot;&gt;EIP-3529&lt;&#x2F;a&gt; (introduced in the London hard fork). This greatly reduces the refunds for transiently-set storage slots in otherwise low-cost transactions. For example, in order to receive the full refund of one re-entrancy lock, the transaction must spend ~80k gas on other operations.&lt;&#x2F;p&gt;
&lt;p&gt;Language support could be added in relatively easy way. For example, in Solidity, a qualifier &lt;code&gt;transient&lt;&#x2F;code&gt; can be introduced (similar to the existing qualifiers &lt;code&gt;memory&lt;&#x2F;code&gt; and &lt;code&gt;storage&lt;&#x2F;code&gt;, and Java&#x27;s own &lt;code&gt;transient&lt;&#x2F;code&gt; keyword with a similar meaning). Since the addressing scheme of &lt;code&gt;TSTORE&lt;&#x2F;code&gt; and &lt;code&gt;TLOAD&lt;&#x2F;code&gt; is the same as for &lt;code&gt;SSTORE&lt;&#x2F;code&gt; and &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, code generation routines that exist for storage variables, can be easily generalised to also support transient storage.&lt;&#x2F;p&gt;
&lt;p&gt;Potential use cases enabled or improved by this EIP include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reentrancy locks&lt;&#x2F;li&gt;
&lt;li&gt;On-chain computable CREATE2 addresses: constructor arguments are read from the factory contract instead of passed as part of init code hash&lt;&#x2F;li&gt;
&lt;li&gt;Single transaction &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; approvals, e.g. &lt;code&gt;#temporaryApprove(address spender, uint256 amount)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fee-on-transfer contracts: pay a fee to a token contract to unlock transfers for the duration of a transaction&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Till&quot; pattern: allowing users to perform all actions as part of a callback, and checking the &quot;till&quot; is balanced at the end&lt;&#x2F;li&gt;
&lt;li&gt;Proxy call metadata: pass additional metadata to an implementation contract without using calldata, e.g. values of immutable proxy constructor arguments&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;These opcodes are more efficient to execute than the &lt;code&gt;SSTORE&lt;&#x2F;code&gt; and &lt;code&gt;SLOAD&lt;&#x2F;code&gt; opcodes because the original value never needs to be loaded from storage (i.e. is always 0). The gas accounting rules are also simpler, since no refunds are required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Two new opcodes are added to EVM, &lt;code&gt;TLOAD&lt;&#x2F;code&gt; (&lt;code&gt;0x5c&lt;&#x2F;code&gt;) and &lt;code&gt;TSTORE&lt;&#x2F;code&gt; (&lt;code&gt;0x5d&lt;&#x2F;code&gt;). (Note that previous drafts of this EIP specified the values &lt;code&gt;0xb3&lt;&#x2F;code&gt; and &lt;code&gt;0xb4&lt;&#x2F;code&gt; for &lt;code&gt;TLOAD&lt;&#x2F;code&gt; and &lt;code&gt;TSTORE&lt;&#x2F;code&gt; respectively to avoid conflict with other EIPs. The conflict has since been removed.)&lt;&#x2F;p&gt;
&lt;p&gt;They use the same arguments on stack as &lt;code&gt;SLOAD&lt;&#x2F;code&gt; (&lt;code&gt;0x54&lt;&#x2F;code&gt;) and &lt;code&gt;SSTORE&lt;&#x2F;code&gt; (&lt;code&gt;0x55&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;TLOAD&lt;&#x2F;code&gt; pops one 32-byte word from the top of the stack, treats this value as the address, fetches 32-byte word from the transient storage at that address, and pushes the value on top of the stack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;TSTORE&lt;&#x2F;code&gt; pops two 32-byte words from the top of the stack. The word on the top is the address, and the next is the value. &lt;code&gt;TSTORE&lt;&#x2F;code&gt; saves the value at the given address in the transient storage.&lt;&#x2F;p&gt;
&lt;p&gt;Addressing is the same as &lt;code&gt;SLOAD&lt;&#x2F;code&gt; and &lt;code&gt;SSTORE&lt;&#x2F;code&gt;. i.e. each 32-byte address points to a unique 32-byte word.&lt;&#x2F;p&gt;
&lt;p&gt;Gas cost for &lt;code&gt;TSTORE&lt;&#x2F;code&gt; is the same as a warm &lt;code&gt;SSTORE&lt;&#x2F;code&gt; of a dirty slot (i.e. original value is not new value and is not current value, currently 100 gas), and gas cost of &lt;code&gt;TLOAD&lt;&#x2F;code&gt; is the same as a hot &lt;code&gt;SLOAD&lt;&#x2F;code&gt; (value has been read before, currently 100 gas). Gas cost cannot be on par with memory access due to transient storage&#x27;s interactions with reverts.&lt;&#x2F;p&gt;
&lt;p&gt;All values in transient storage are discarded at the end of the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Transient storage is private to the contract that owns it, in the same way as persistent storage. Only owning contract frames may access their transient storage. And when they do, all the frames access the same transient store, in the same way as persistent storage, but unlike memory.&lt;&#x2F;p&gt;
&lt;p&gt;When transient storage is used in the context of &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; or &lt;code&gt;CALLCODE&lt;&#x2F;code&gt;, then the owning contract of the transient storage is the contract that issued &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; or &lt;code&gt;CALLCODE&lt;&#x2F;code&gt; instruction (the caller) as with persistent storage. When transient storage is used in the context of &lt;code&gt;CALL&lt;&#x2F;code&gt; or &lt;code&gt;STATICCALL&lt;&#x2F;code&gt;, then the owning contract of the transient storage is the contract that is the target of the &lt;code&gt;CALL&lt;&#x2F;code&gt; or &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; instruction (the callee).&lt;&#x2F;p&gt;
&lt;p&gt;If a frame reverts, all writes to transient storage that took place between entry to the frame and the return are reverted, including those that took place in inner calls.  This mimics the behavior of persistent storage.&lt;&#x2F;p&gt;
&lt;p&gt;If the &lt;code&gt;TSTORE&lt;&#x2F;code&gt; opcode is called within the context of a &lt;code&gt;STATICCALL&lt;&#x2F;code&gt;, it will result in an exception instead of performing the modification. &lt;code&gt;TLOAD&lt;&#x2F;code&gt; is allowed within the context of a &lt;code&gt;STATICCALL&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The behavior of the opcodes for transient storage differs from the opcodes for storage in that &lt;code&gt;TSTORE&lt;&#x2F;code&gt; does not require &lt;em&gt;gasleft&lt;&#x2F;em&gt;, as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt;, to be less than or equal to the gas stipend (currently 2,300).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Another option to solve the problem of inter-frame communication is repricing the &lt;code&gt;SSTORE&lt;&#x2F;code&gt; and &lt;code&gt;SLOAD&lt;&#x2F;code&gt; opcodes to be cheaper for the transient storage use case. This has already been done as of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2200&#x2F;&quot;&gt;EIP-2200&lt;&#x2F;a&gt;. However, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3529&#x2F;&quot;&gt;EIP-3529&lt;&#x2F;a&gt; reduced the maximum refund to only 20% of the transaction gas cost, which means the use of transient storage is severely limited.&lt;&#x2F;p&gt;
&lt;p&gt;Another approach is to keep the refund counter for transient storage separate from the refund counter for other storage uses, and remove the refund cap for transient storage. However, that approach is more complex to implement and understand. For example, the 20% refund cap must be applied to the gas used &lt;em&gt;after&lt;&#x2F;em&gt; subtracting the uncapped gas refund. Otherwise, the refund amount available subject to the 20% refund cap could be increased by executing transient storage writes. Thus it is preferable to have a separate mechanism that does not interact with the refund counter. Future hard forks can remove the complex refund behavior meant to support the transient storage use case, encouraging migration to contracts that are more efficient for the Ethereum clients to execute.&lt;&#x2F;p&gt;
&lt;p&gt;There is a known objection to the word-addressed storage-like interface of the &lt;code&gt;TSTORE&lt;&#x2F;code&gt; and &lt;code&gt;TLOAD&lt;&#x2F;code&gt; opcodes since transient storage is more akin to memory than storage in lifecycle. A byte-addressed memory-like interface is another option. The storage-like word-addressed interface is preferred due to the usefulness of mappings in combination with the transaction-scoped memory region. Often times, you will need to keep transient state with arbitrary keys, such as in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; temporary approval use case which uses a mapping of &lt;code&gt;(owner, spender)&lt;&#x2F;code&gt; to &lt;code&gt;allowance&lt;&#x2F;code&gt;. Mappings are difficult to implement using linear memory, and linear memory must also have dynamic gas costs. It is also more complicated to handle reverts with a linear memory. It is possible to have a memory-like interface while the underlying implementation uses a map to allow for storage in arbitrary offsets, but this would result in a third memory-storage hybrid interface that would require new code paths in compilers.&lt;&#x2F;p&gt;
&lt;p&gt;Some think that a unique transaction identifier may obviate the need for transient storage as described in this EIP. This is a misconception: a transaction identifier used in combination with regular storage has all the same issues that motivate this EIP. The two features are orthogonal.&lt;&#x2F;p&gt;
&lt;p&gt;Relative cons of this transient storage EIP:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does not address transient usages of storage in existing contracts&lt;&#x2F;li&gt;
&lt;li&gt;New code in the clients&lt;&#x2F;li&gt;
&lt;li&gt;New concept for the yellow paper (more to update)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Relative pros of this transient storage EIP:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Transient storage opcodes are considered separately in protocol upgrades and not inadvertently broken (e.g. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;3529&#x2F;&quot;&gt;EIP-3529&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Clients do not need to load the original value&lt;&#x2F;li&gt;
&lt;li&gt;No upfront gas cost to account for non-transient writes&lt;&#x2F;li&gt;
&lt;li&gt;Does not change the semantics of the existing operations&lt;&#x2F;li&gt;
&lt;li&gt;No need to clear storage slots after usage&lt;&#x2F;li&gt;
&lt;li&gt;Simpler gas accounting rules&lt;&#x2F;li&gt;
&lt;li&gt;Future storage designs (e.g. Verkle tree) do not need to account for transient storage refunds&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP requires a hard fork to implement.&lt;&#x2F;p&gt;
&lt;p&gt;Since this EIP does not change behavior of any existing opcodes, it is backwards compatible with all existing smart contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;A test suite for this EIP can be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;execution-spec-tests&#x2F;tree&#x2F;1983444bbe1a471886ef7c0e82253ffe2a4053e1&#x2F;tests&#x2F;cancun&#x2F;eip1153_tstore&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Because the transient storage must behave almost identically to storage within the context of a single transaction with regards to revert behavior, it is necessary to be able to revert to a previous state of transient storage within a transaction. At the same time reverts are exceptional cases and loads, stores and returns should be cheap.&lt;&#x2F;p&gt;
&lt;p&gt;A map of current state plus a journal of all changes and a list of checkpoints is recommended. This has the following time complexities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On entry to a call frame, a call marker is added to the list - &lt;code&gt;O(1)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;New values are written to the current state, and the previous value is written to the journal - &lt;code&gt;O(1)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;When a call exits successfully, the marker to the journal index of when that call was entered is discarded - &lt;code&gt;O(1)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;On revert all entries are reverted up to the last checkpoint, in reverse - &lt;code&gt;O(N)&lt;&#x2F;code&gt; where &lt;code&gt;N&lt;&#x2F;code&gt; = number of journal entries since last checkpoint&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; JournalEntry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    prevValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&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 class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Journal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; JournalEntry&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Checkpoints&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Journal&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Current&lt;&#x2F;span&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;span class=&quot;z-variable&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&gt;        [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; EMPTY_VALUE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TransientStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The current state of transient storage.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * All changes are written to the journal. On revert, we apply the changes in reverse to the last checkpoint.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; journal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Journal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The length of the journal at the time of each checkpoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; checkpoints&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Checkpoints&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Returns the current value of the given contract address and key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The key of transient storage for the address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;?.&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ??&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; EMPTY_VALUE&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Set the current value in the map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the address of the contract for which the key is being set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the slot to set for the address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the new value of the slot to set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; put&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&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 class=&quot;z-variable z-other&quot;&gt;            key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prevValue&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ??&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Commit all the changes since the last checkpoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;checkpoints&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Nothing to commit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;checkpoints&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pop&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The last checkpoint is discarded.&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * To be called whenever entering a new context. If revert is called after checkpoint, all changes made after the latest checkpoint are reverted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checkpoint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;checkpoints&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&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&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Revert transient storage to the state from the last call to checkpoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; lastCheckpoint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;checkpoints&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pop&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;typeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; lastCheckpoint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;undefined&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Nothing to revert&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; lastCheckpoint&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; prevValue&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; we can assume it exists, since it was written in the journal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;            this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;current&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; prevValue&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 class=&quot;z-variable z-language&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;splice&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;lastCheckpoint&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; lastCheckpoint&lt;&#x2F;span&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;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 worst case time complexity can be produced by writing the maximum number of keys that can fit in one block, and then reverting. In this case, the client is required to do twice as many writes to apply all the entries in the journal. However, the same case applies to the state journaling implementation of existing clients, and cannot be DOS&#x27;d with the following code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; =0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; TryDOS&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; slot&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tryDOS&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;gasleft&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5000&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            unchecked&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                slot &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;TSTORE&lt;&#x2F;code&gt; presents a new way to allocate memory on a node with linear cost. In other words, each TSTORE allows the developer to store 32 bytes for 100 gas, excluding any other required operations to prepare the stack. Given 30 million gas, the maximum amount of memory that can be allocated using TSTORE is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;30M gas * 1 TSTORE &#x2F; 100 gas * 32 bytes &#x2F; 1 TSTORE * 1MB &#x2F; 2^20 bytes ~= 9.15MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Given the same amount of gas, the maximum amount of memory that can be allocated in a single context by &lt;code&gt;MSTORE&lt;&#x2F;code&gt; is ~3.75MB:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;30M gas = 3x + x^2 &#x2F; 512 =&amp;gt; x = ~123,169 32-byte words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~123,169 words * 32 bytes&#x2F;word * 1MB &#x2F; 2^20 bytes = 3.75MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, if you only spend 1M gas allocating memory in each context, and make calls to reset the memory expansion cost, you can allocate ~700KB per million gas, for a total of ~20MB of memory allocated:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1M gas = 3x + x^2 &#x2F; 512 =&amp;gt; x = ~21,872 32-byte words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;30M gas * ~21,872 words &#x2F; 1M gas * 32 bytes&#x2F;word * 1MB &#x2F; 2^20 bytes = ~20MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Smart contract developers should understand the lifetime of transient storage variables before use. Because transient storage is automatically cleared at the end of the transaction, smart contract developers may be tempted to avoid clearing slots as part of a call in order to save gas. However, this could prevent further interactions with the contract in the same transaction (e.g. in the case of re-entrancy locks) or cause other bugs, so smart contract developers should be careful to &lt;em&gt;only&lt;&#x2F;em&gt; leave transient storage slots with nonzero values when those slots are intended to be used by future calls within the same transaction. Otherwise, these opcodes behave exactly the same as &lt;code&gt;SSTORE&lt;&#x2F;code&gt; and &lt;code&gt;SLOAD&lt;&#x2F;code&gt;, so all the usual security considerations apply especially in regard to reentrancy risk.&lt;&#x2F;p&gt;
&lt;p&gt;Smart contract developers may also be tempted to use transient storage as an alternative to in-memory mappings. They should be aware that transient storage is not discarded when a call returns or reverts, as is memory, and should prefer memory for these use cases so as not to create unexpected behavior on reentrancy in the same transaction. The necessarily high cost of transient storage over memory should already discourage this usage pattern. Most usages of in-memory mappings can be better implemented with key-sorted lists of entries, and in-memory mappings are rarely required in smart contracts (i.e. the author knows of no known use cases in production).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Contract Ownership Standard</title>
        <published>2018-06-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Mudge</name><uri>https://github.com/mudgen</uri>
	</author>
	
	<author>
		<name>Dan Finlay</name><email>dan@danfinlay.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/173/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/173" />
        

        <id>https://wg-eips.ritovision.com/173/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:173"
            label="ERC-173" />
        

        
        

        
        <summary type="html">A standard interface for ownership of contracts</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/173/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specification defines standard functions for owning or controlling a contract.&lt;&#x2F;p&gt;
&lt;p&gt;An implementation allows reading the current owner (&lt;code&gt;owner() returns (address)&lt;&#x2F;code&gt;) and transferring ownership (&lt;code&gt;transferOwnership(address newOwner)&lt;&#x2F;code&gt;) along with a standardized event for when ownership is changed (&lt;code&gt;OwnershipTransferred(address indexed previousOwner, address indexed newOwner)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many smart contracts require that they be owned or controlled in some way. For example to withdraw funds or perform administrative actions. It is so common that the contract interface used to handle contract ownership should be standardized to allow compatibility with user interfaces and contracts that manage contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some examples of kinds of contracts and applications that can benefit from this standard:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Exchanges that buy&#x2F;sell&#x2F;auction ethereum contracts. This is only widely possible if there is a standard for getting the owner of a contract and transferring ownership.&lt;&#x2F;li&gt;
&lt;li&gt;Contract wallets that hold the ownership of contracts and that can transfer the ownership of contracts.&lt;&#x2F;li&gt;
&lt;li&gt;Contract registries. It makes sense for some registries to only allow the owners of contracts to add&#x2F;remove their contracts. A standard must exist for these contract registries to verify that a contract is being submitted by the owner of it before accepting it.&lt;&#x2F;li&gt;
&lt;li&gt;User interfaces that show and transfer ownership of contracts.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Every ERC-173 compliant contract must implement the &lt;code&gt;ERC173&lt;&#x2F;code&gt; interface. Contracts should also implement &lt;code&gt;ERC165&lt;&#x2F;code&gt; for the ERC-173 interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-173 Contract Ownership Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x7f5828d0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC173&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when ownership of a contract changes.    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; OwnershipTransferred&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; previousOwner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newOwner&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the address of the owner    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Set the address of the new owner of the contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Set _newOwner to address(0) to renounce any ownership.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newOwner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address of the new owner of the contract    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferOwnership&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newOwner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if a contract implements an interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface identifier, as specified in ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface identification is specified in ERC-165. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if the contract implements `interfaceID` and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `interfaceID` is not 0xffffffff, `false` otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;owner()&lt;&#x2F;code&gt; function may be implemented as &lt;code&gt;pure&lt;&#x2F;code&gt; or &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;transferOwnership(address _newOwner)&lt;&#x2F;code&gt; function may be implemented as &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To renounce any ownership of a contract set &lt;code&gt;_newOwner&lt;&#x2F;code&gt; to the zero address: &lt;code&gt;transferOwnership(address(0))&lt;&#x2F;code&gt;. If this is done then a contract is no longer owned by anybody.&lt;&#x2F;p&gt;
&lt;p&gt;The OwnershipTransferred event should be emitted when a contract is created.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Key factors influencing the standard:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Keeping the number of functions in the interface to a minimum to prevent contract bloat.&lt;&#x2F;li&gt;
&lt;li&gt;Backwards compatibility with existing contracts.&lt;&#x2F;li&gt;
&lt;li&gt;Simplicity&lt;&#x2F;li&gt;
&lt;li&gt;Gas efficient&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Several ownership schemes were considered. The scheme chosen in this standard was chosen because of its simplicity, low gas cost and backwards compatibility with existing contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Here are other schemes that were considered:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Associating an Ethereum Name Service (ENS) domain name with a contract.&lt;&#x2F;strong&gt; A contract&#x27;s &lt;code&gt;owner()&lt;&#x2F;code&gt; function could look up the owner address of a particular ENS name and use that as the owning address of the contract. Using this scheme a contract could be transferred by transferring the ownership of the ENS domain name to a different address. Short comings to this approach are that it is not backwards compatible with existing contracts and requires gas to make external calls to ENS related contracts to get the owner address.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Associating an ERC721-based non-fungible token (NFT) with a contract.&lt;&#x2F;strong&gt; Ownership of a contract could be tied to the ownership of an NFT. The benefit of this approach is that the existing ERC721-based infrastructure could be used to sell&#x2F;buy&#x2F;auction contracts. Short comings to this approach are additional complexity and infrastructure required. A contract could be associated with a particular NFT but the NFT would not track that it had ownership of a contract unless it was programmed to track contracts. In addition handling ownership of contracts this way is not backwards compatible.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This standard does not exclude the above ownership schemes or other schemes from also being implemented in the same contract. For example a contract could implement this standard and also implement the other schemes so that ownership could be managed and transferred in multiple ways. This standard does provide a simple ownership scheme that is backwards compatible, is light-weight and simple to implement, and can be widely adopted and depended on.&lt;&#x2F;p&gt;
&lt;p&gt;This standard can be (and has been) extended by other standards to add additional ownership functionality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;If the address returned by &lt;code&gt;owner()&lt;&#x2F;code&gt; is an externally owned account then its private key must not be lost or compromised.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Many existing contracts already implement this standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Reduce alt_bn128 precompile gas costs</title>
        <published>2018-05-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Antonio Salazar Cardozo</name><uri>https://github.com/shadowfiend</uri>
	</author>
	
	<author>
		<name>Zachary Williamson</name><uri>https://github.com/zac-williamson</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1108/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1108-reduce-alt-bn128-precompile-gas-costs/3206" />
        

        <id>https://wg-eips.ritovision.com/1108/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1108"
            label="EIP-1108" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1108/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The elliptic curve arithmetic precompiles are currently overpriced. Re-pricing the precompiles would greatly assist a number of privacy solutions and scaling solutions on Ethereum.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Changes in 2018 to the underlying library used by the official Go reference
implementation led to significant performance gains for the &lt;code&gt;ECADD&lt;&#x2F;code&gt;, &lt;code&gt;ECMUL&lt;&#x2F;code&gt;,
and pairing check precompiled contracts on the &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; elliptic curve.&lt;&#x2F;p&gt;
&lt;p&gt;In the Parity client, field operations used by the precompile algorithms were optimized in 2018,
and recent changes to the pairing algorithm used by the &lt;code&gt;bn&lt;&#x2F;code&gt; crate have brought considerable speedups.&lt;&#x2F;p&gt;
&lt;p&gt;Faster operations on Ethereum clients should be reflected in reduced gas costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Recently, the underlying library used by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&quot;&gt;official Go reference
implementation&lt;&#x2F;a&gt; to implement the
&lt;code&gt;ECADD&lt;&#x2F;code&gt; (at address &lt;code&gt;0x06&lt;&#x2F;code&gt;), &lt;code&gt;ECMUL&lt;&#x2F;code&gt; (at address &lt;code&gt;0x07&lt;&#x2F;code&gt;), and pairing check (at
address &lt;code&gt;0x08&lt;&#x2F;code&gt;) precompiled contracts was shifted to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cloudflare&#x2F;bn256&quot;&gt;Cloudflare&#x27;s bn256
library&lt;&#x2F;a&gt;. Based on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;16203&quot;&gt;initial PR that
introduced this change&lt;&#x2F;a&gt;,
and corroborated in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;16301#issuecomment-372687543&quot;&gt;a later
note&lt;&#x2F;a&gt;,
the computational cost of &lt;code&gt;ECADD&lt;&#x2F;code&gt;, &lt;code&gt;ECMUL&lt;&#x2F;code&gt;, and pairing checks (excepting the
constant) has dropped roughly an order of magnitude across the board.&lt;&#x2F;p&gt;
&lt;p&gt;Also, optimizations in the bn library &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;bn&#x2F;pull&#x2F;9&quot;&gt;in 2018&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;bn&#x2F;pull&#x2F;14&quot;&gt;2019&lt;&#x2F;a&gt;
used by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity-ethereum&quot;&gt;Parity client&lt;&#x2F;a&gt; led to a
significant performance boost we
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;zac-williamson&#x2F;838410a3da179d47d31b25b586c15e53&quot;&gt;benchmarked&lt;&#x2F;a&gt;
and compared against the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;pdyraga&#x2F;4649b74436940a01e8221d85e80bfeef&quot;&gt;previous
results&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Following is a table with the current gas cost and new gas cost:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Contract&lt;&#x2F;th&gt;&lt;th&gt;Address&lt;&#x2F;th&gt;&lt;th&gt;Current Gas Cost&lt;&#x2F;th&gt;&lt;th&gt;Updated Gas Cost&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ECADD&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x06&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;500&lt;sup&gt;[1]&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;150&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ECMUL&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x07&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;40 000&lt;sup&gt;[1]&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;6 000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Pairing check&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;0x08&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;80 000 * k + 100 000&lt;sup&gt;[2]&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;34 000 * k + 45 000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The gas costs for &lt;code&gt;ECADD&lt;&#x2F;code&gt; and &lt;code&gt;ECMUL&lt;&#x2F;code&gt; are updates to the costs listed in
EIP-196, while the gas costs for the pairing check are updates to the cost
listed in EIP-197. Updated gas costs have been adjusted to the less performant
client which is Parity, according to benchmarks&lt;sup&gt;[3]&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To come up with these updates gas costs, the performance of the &lt;code&gt;ecrecover&lt;&#x2F;code&gt; precompile
was measured at 116 microseconds per &lt;code&gt;ecrecover&lt;&#x2F;code&gt; invocation. Assuming the &lt;code&gt;ecrecover&lt;&#x2F;code&gt;
gas price is fair at 3,000 gas, we get a price of 25.86 gas per microsecond of a precompile
algorithm&#x27;s runtime. With this in mind, the pairing precompile took 3,037 microseconds to
compute 1 pairing, and 14,663 microseconds to compute 10 pairings. From this, the pairing
algorithm has a fixed &#x27;base&#x27; run-time of 1,745 microseconds, plus 1,292 microseconds per
pairing. We can split the run-time into &#x27;fixed cost&#x27; and &#x27;linear cost per pairing&#x27;
components because of the structure of the algorithm.&lt;&#x2F;p&gt;
&lt;p&gt;Thus using a &#x27;fair&#x27; price of 25.86 gas per microsecond, we get a gas formula of
~&lt;code&gt;35,000 * k + 45,000&lt;&#x2F;code&gt; gas, where &lt;code&gt;k&lt;&#x2F;code&gt; is the number of pairings being computed. [4]&lt;&#x2F;p&gt;
&lt;p&gt;[1]- Per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;196&#x2F;&quot;&gt;EIP-196&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;[2]- Per &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;197&#x2F;&quot;&gt;EIP-197&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;[3]- &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;zac-williamson&#x2F;838410a3da179d47d31b25b586c15e53&quot;&gt;Parity benchmarks.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[4]- &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;pull&#x2F;1987#discussion_r280977066&quot;&gt;PR comment clarifying gas cost math&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;existing-protocols-would-benefit-immensely-from-cheaper-elliptic-curve-cryptography&quot;&gt;Existing protocols would benefit immensely from cheaper elliptic curve cryptography&lt;&#x2F;h3&gt;
&lt;p&gt;Fast elliptic curve cryptography is a keystone of a growing number of protocols built on top of Ethereum. To list a few:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AztecProtocol&#x2F;AZTEC&quot;&gt;The AZTEC protocol&lt;&#x2F;a&gt; utilizes the elliptic curve precompiles to construct private tokens, with zero-knowledge transaction logic, via the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;1723&quot;&gt;ERC-1723&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;1724&quot;&gt;ERC-1724&lt;&#x2F;a&gt; standard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;matter-labs&#x2F;matter-network&quot;&gt;Matter Labs&lt;&#x2F;a&gt; utilizes the precompiles to implement Ignis, a scaling solution with a throughput of 500txns per second&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rollup&#x2F;rollup&quot;&gt;Rollup&lt;&#x2F;a&gt; utilizes the precompiles to create L2 scaling solutions, where the correctness of transactions is guaranteed by main-net, without an additional consensus layer&lt;&#x2F;li&gt;
&lt;li&gt;ZEther&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; uses precompiles &lt;code&gt;ECADD&lt;&#x2F;code&gt; and &lt;code&gt;ECMUL&lt;&#x2F;code&gt; to construct confidential transactions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To give a concrete example, it currently costs &lt;code&gt;820,000&lt;&#x2F;code&gt; gas to validate the cryptography in a typical AZTEC confidential transaction. If the gas schedule for the precompiles correctly reflected their load on the Ethereum network, this cost would be &lt;code&gt;197,000&lt;&#x2F;code&gt; gas. This significantly increases the potential use cases for private assets on Ethereum. AZTEC is planning to deploy several cryptographic protocols Ethereum, but these are at the limits of what is practical given the current precompile costs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Confidential weighted voting&lt;&#x2F;li&gt;
&lt;li&gt;Partial-order filling over encrypted orders, for private decentralized exchanges&lt;&#x2F;li&gt;
&lt;li&gt;Anonymous identity sharing proofs (e.g. proving you are on a whitelist, without revealing who you are)&lt;&#x2F;li&gt;
&lt;li&gt;Many-to-one payments and one-to-many confidential payments, as encrypted communication channels between main-net and L2 applications&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For zk-SNARK based protocols on Ethereum, EIP-1108 will not only reduce the gas costs of verifying zk-SNARKs substantially, but can also aid in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;matter-labs&#x2F;Groth16BatchVerifier&quot;&gt;batching together multiple zk-SNARK proofs&lt;&#x2F;a&gt;. This is also a technique that can be used to split up monolithic zk-SNARK circuits into a batch of zk-SNARKs with smaller individual circuit sizes, which makes zk-SNARKs both easier to construct and deploy.&lt;&#x2F;p&gt;
&lt;p&gt;ZEther transactions currently cost ~&lt;code&gt;6,000,000&lt;&#x2F;code&gt; gas. This EIP would reduce this to ~&lt;code&gt;1,000,000&lt;&#x2F;code&gt; gas, which makes the protocol more practical.&lt;&#x2F;p&gt;
&lt;p&gt;To summarise, there are several protocols that currently exist on main-net, that would benefit immensely from this EIP. Elliptic curve cryptography can provide valuable solutions for Ethereum, such as scaling and privacy, and the scope and scale of these solutions can be increased if the gas costs for the &lt;code&gt;bn128&lt;&#x2F;code&gt; precompiles accurately reflects their computational load on the network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cheaper-elliptic-curve-cryptography-can-be-used-to-trade-storage-for-computation&quot;&gt;Cheaper elliptic curve cryptography can be used to trade storage for computation&lt;&#x2F;h3&gt;
&lt;p&gt;Solutions such as Rollup and Ignis can be used to batch groups of individual transactions into a zk-SNARK proof, with the on-chain state being represented by a small Merkle root, instead of multiple account balances.&lt;&#x2F;p&gt;
&lt;p&gt;If zk-SNARK verification costs are decreased, these solutions can be deployed for a wider range of use cases and more Rollup-style transactions can be processed per block.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parity-and-geth-already-have-fast-algorithms-that-justify-reduced-gas-costs&quot;&gt;Parity and Geth already have fast algorithms that justify reduced gas costs&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP does not require Parity or Geth to deploy new cryptographic libraries, as fast bn128 algorithms have already been integrated into these clients. This goal of proposing this EIP for Istanbul, is to supplement &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1829&#x2F;&quot;&gt;EIP-1829&lt;&#x2F;a&gt; (arithmetic over generic elliptic curves), providing an immediate solution to the pressing problem of expensive cryptography, while more advanced solutions are developed, defined and deployed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;As no underlying algorithms are being changed, there are no additional test cases to specify.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Both the Parity and Geth clients have already implemented cryptographic libraries that are fast enough to justify reducing the precompile gas costs. As a reference, here are a list of elliptic curve libraries, in &lt;code&gt;C++&lt;&#x2F;code&gt;, &lt;code&gt;golang&lt;&#x2F;code&gt; and &lt;code&gt;rust&lt;&#x2F;code&gt;, that support the &lt;code&gt;bn128&lt;&#x2F;code&gt; curve, and have run-times that are equal to or faster than the Parity benchmarks.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;bn&quot;&gt;Parity bn crate (rust)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;tree&#x2F;master&#x2F;crypto&#x2F;bn256&#x2F;cloudflare&quot;&gt;Geth bn256 library (golang)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;herumi&#x2F;mcl&quot;&gt;MCL, a portable C++ pairing library&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;scipr-lab&#x2F;libff&quot;&gt;Libff, a C++ pairing library used in many zk-SNARK libraries&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;additional-references&quot;&gt;Additional References&lt;&#x2F;h2&gt;
&lt;p&gt;@vbuterin independently proposed a similar reduction after this EIP was originally created, with similar rationale, as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;1187&quot;&gt;ethereum&#x2F;EIPs#1187&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Bünz, B., Agrawal, S., Zamani, M., &amp;amp; Boneh, D. (2020). Zether: Towards Privacy in a Smart Contract World. In J. Bonneau &amp;amp; N. Heninger (Eds.), &lt;span style=&quot;font-style: italic;&quot;&gt;Financial Cryptography and Data Security&lt;&#x2F;span&gt;. https:&#x2F;&#x2F;doi.org&#x2F;&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;978-3-030-51280-4_23&quot;&gt;10.1007&#x2F;978-3-030-51280-4_23&lt;&#x2F;a&gt;These are all technologies that have been, or are in the process of being, deployed to main-net. These protocols would all benefit from reducing the gas cost of the precompiles. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>EXTCODEHASH opcode</title>
        <published>2018-05-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><email>arachnid@notdot.net</email>
	</author>
	
	<author>
		<name>Paweł Bylica</name><email>pawel@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1052/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/extcodehash-opcode/262" />
        

        <id>https://wg-eips.ritovision.com/1052/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1052"
            label="EIP-1052" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1052/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP specifies a new opcode, which returns the keccak256 hash of a contract&#x27;s code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Many contracts need to perform checks on a contract&#x27;s bytecode, but do not necessarily need the bytecode itself. For instance, a contract may want to check if another contract&#x27;s bytecode is one of a set of permitted implementations, or it may perform analyses on code and whitelist any contract with matching bytecode if the analysis passes.&lt;&#x2F;p&gt;
&lt;p&gt;Contracts can presently do this using the &lt;code&gt;EXTCODECOPY&lt;&#x2F;code&gt; (&lt;code&gt;0x3c&lt;&#x2F;code&gt;) opcode, but this is expensive, especially for large contracts, in cases where only the hash is required. As a result, we propose a new opcode, &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;, which returns the keccak256 hash of a contract&#x27;s bytecode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;A new opcode, &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;, is introduced, with number &lt;code&gt;0x3f&lt;&#x2F;code&gt;. The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt;
takes one argument from the stack, zeros the first 96 bits
and pushes to the stack the keccak256 hash of the code of the account
at the address being the remaining 160 bits.&lt;&#x2F;p&gt;
&lt;p&gt;In case the account does not exist or is empty (as defined by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;161&#x2F;&quot;&gt;EIP-161&lt;&#x2F;a&gt;) &lt;code&gt;0&lt;&#x2F;code&gt; is pushed to the stack.&lt;&#x2F;p&gt;
&lt;p&gt;In case the account does not have code the keccak256 hash of empty data
(i.e. &lt;code&gt;c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470&lt;&#x2F;code&gt;)
is pushed to the stack.&lt;&#x2F;p&gt;
&lt;p&gt;The gas cost of the &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; is 400.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;As described in the motivation section, this opcode is widely useful, and saves
on wasted gas in many cases.&lt;&#x2F;p&gt;
&lt;p&gt;The gas cost is the same as the gas cost for the &lt;code&gt;BALANCE&lt;&#x2F;code&gt; opcode because the
execution of the &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; requires the same account lookup as in &lt;code&gt;BALANCE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Only the 20 last bytes of the argument are significant (the first 12 bytes are
ignored) similarly to the semantics of the &lt;code&gt;BALANCE&lt;&#x2F;code&gt; (&lt;code&gt;0x31&lt;&#x2F;code&gt;), &lt;code&gt;EXTCODESIZE&lt;&#x2F;code&gt; (&lt;code&gt;0x3b&lt;&#x2F;code&gt;) and
&lt;code&gt;EXTCODECOPY&lt;&#x2F;code&gt; (&lt;code&gt;0x3c&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; distinguishes accounts without code and non-existing accounts.
This is consistent with the way accounts are represented in the state trie.
This also allows smart contracts to check whether an account exists.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There are no backwards compatibility concerns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of the account without code is &lt;code&gt;c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470&lt;&#x2F;code&gt;
what is the keccak256 hash of empty data.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of non-existent account is &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of a precompiled contract is either &lt;code&gt;c5d246...&lt;&#x2F;code&gt; or &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of &lt;code&gt;A&lt;&#x2F;code&gt; is &lt;code&gt;X&lt;&#x2F;code&gt;, then &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of &lt;code&gt;A + 2**160&lt;&#x2F;code&gt; is &lt;code&gt;X&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an account that selfdestructed in the current transaction.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an account that selfdestructed and later the selfdestruct has been reverted.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an account created in the current transaction.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an account that has been newly created and later the creation has been reverted.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an account that firstly does not exist and later is empty.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;EXTCODEHASH&lt;&#x2F;code&gt; of an empty account that is going to be cleared by the state clearing rule.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;TBD&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Constantinople&quot;</title>
        <published>2018-04-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Nick Savers</name><uri>https://github.com/nicksavers</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1013/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/1013/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:1013"
            label="EIP-1013" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1013/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This meta-EIP specifies the changes included in the Ethereum hardfork named Constantinople.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Constantinople&lt;&#x2F;li&gt;
&lt;li&gt;Aliases: Metropolis&#x2F;Constantinople, Metropolis part 2&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 7_280_000&lt;&#x2F;code&gt; on the Ethereum Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 4,230,000&lt;&#x2F;code&gt; on the Ropsten testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 9_200_000&lt;&#x2F;code&gt; on the Kovan testnet&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Block &amp;gt;= 3_660_663&lt;&#x2F;code&gt; on the Rinkeby testnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Included EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;145&#x2F;&quot;&gt;EIP-145&lt;&#x2F;a&gt;: Bitwise shifting instructions in EVM&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1014&#x2F;&quot;&gt;EIP-1014&lt;&#x2F;a&gt;: Skinny CREATE2&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1052&#x2F;&quot;&gt;EIP-1052&lt;&#x2F;a&gt;: EXTCODEHASH Opcode&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1234&#x2F;&quot;&gt;EIP-1234&lt;&#x2F;a&gt;: Delay difficulty bomb, adjust block reward&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1283&#x2F;&quot;&gt;EIP-1283&lt;&#x2F;a&gt;: Net gas metering for SSTORE without dirty maps&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;The list above includes the EIPs discussed as candidates for Constantinople at the All Core Dev &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;issues&#x2F;55&quot;&gt;Constantinople Session #1&lt;&#x2F;a&gt;. See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;wiki&#x2F;Constantinople-Progress-Tracker&quot;&gt;Constantinople Progress Tracker&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2019&#x2F;02&#x2F;22&#x2F;ethereum-constantinople-st-petersburg-upgrade-announcement&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Skinny CREATE2</title>
        <published>2018-04-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1014/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/1014/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:1014"
            label="EIP-1014" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1014/">&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;Adds a new opcode (&lt;code&gt;CREATE2&lt;&#x2F;code&gt;) at &lt;code&gt;0xf5&lt;&#x2F;code&gt;, which takes 4 stack arguments: endowment, memory_start, memory_length, salt. Behaves identically to &lt;code&gt;CREATE&lt;&#x2F;code&gt; (&lt;code&gt;0xf0&lt;&#x2F;code&gt;), except using &lt;code&gt;keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]&lt;&#x2F;code&gt; instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;CREATE2&lt;&#x2F;code&gt; has the same &lt;code&gt;gas&lt;&#x2F;code&gt; schema as &lt;code&gt;CREATE&lt;&#x2F;code&gt;, but also an extra &lt;code&gt;hashcost&lt;&#x2F;code&gt; of &lt;code&gt;GSHA3WORD * ceil(len(init_code) &#x2F; 32)&lt;&#x2F;code&gt;, to account for the hashing that must be performed. The &lt;code&gt;hashcost&lt;&#x2F;code&gt; is deducted at the same time as memory-expansion gas and &lt;code&gt;CreateGas&lt;&#x2F;code&gt; is deducted: &lt;em&gt;before&lt;&#x2F;em&gt; evaluation of the resulting address and the execution of &lt;code&gt;init_code&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0xff&lt;&#x2F;code&gt; is a single byte,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;address&lt;&#x2F;code&gt; is always &lt;code&gt;20&lt;&#x2F;code&gt; bytes,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;salt&lt;&#x2F;code&gt; is always &lt;code&gt;32&lt;&#x2F;code&gt; bytes (a stack item).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The preimage for the final hashing round is thus always exactly &lt;code&gt;85&lt;&#x2F;code&gt; bytes long.&lt;&#x2F;p&gt;
&lt;p&gt;The coredev-call at 2018-08-10 decided to use the formula above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h3&gt;
&lt;p&gt;Allows interactions to (actually or counterfactually in channels) be made with addresses that do not exist yet on-chain but can be relied on to only possibly eventually contain code that has been created by a particular piece of init code. Important for state-channel use cases that involve counterfactual interactions with contracts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;address-formula&quot;&gt;Address formula&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Ensures that addresses created with this scheme cannot collide with addresses created using the traditional &lt;code&gt;keccak256(rlp([sender, nonce]))&lt;&#x2F;code&gt; formula, as &lt;code&gt;0xff&lt;&#x2F;code&gt; can only be a starting byte for RLP for data many petabytes long.&lt;&#x2F;li&gt;
&lt;li&gt;Ensures that the hash preimage has a fixed size,&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;gas-cost&quot;&gt;Gas cost&lt;&#x2F;h4&gt;
&lt;p&gt;Since address calculation depends on hashing the &lt;code&gt;init_code&lt;&#x2F;code&gt;, it would leave clients open to DoS attacks if executions could repeatedly cause hashing of large pieces of &lt;code&gt;init_code&lt;&#x2F;code&gt;, since expansion of memory is paid for only once. This EIP uses the same cost-per-word as the &lt;code&gt;SHA3&lt;&#x2F;code&gt; opcode.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;clarifications&quot;&gt;Clarifications&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;init_code&lt;&#x2F;code&gt; is the code that, when executed, produces the runtime bytecode that will be placed into the state, and which typically is used by high level languages to implement a &#x27;constructor&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP makes collisions possible. The behaviour at collisions is specified by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;684&quot;&gt;EIP-684&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If a contract creation is attempted, due to either a creation transaction or the &lt;code&gt;CREATE&lt;&#x2F;code&gt; (or future &lt;code&gt;CREATE2&lt;&#x2F;code&gt;) opcode, and the destination address already has either nonzero nonce, or nonempty code, then the creation throws immediately, with exactly the same behavior as would arise if the first byte in the init code were an invalid opcode. This applies retroactively starting from genesis.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Specifically, if &lt;code&gt;nonce&lt;&#x2F;code&gt; or &lt;code&gt;code&lt;&#x2F;code&gt; is nonzero, then the create-operation fails.&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;161&#x2F;&quot;&gt;EIP-161&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Account creation transactions and the &lt;code&gt;CREATE&lt;&#x2F;code&gt; operation SHALL, prior to the execution of the initialisation code, increment the nonce over and above its normal starting value by one&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This means that if a contract is created in a transaction, the &lt;code&gt;nonce&lt;&#x2F;code&gt; is immediately non-zero, with the side-effect that a collision within the same transaction will always fail -- even if it&#x27;s carried out from the &lt;code&gt;init_code&lt;&#x2F;code&gt; itself.&lt;&#x2F;p&gt;
&lt;p&gt;It should also be noted that &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; (&lt;code&gt;0xff&lt;&#x2F;code&gt;) has no immediate effect on &lt;code&gt;nonce&lt;&#x2F;code&gt; or &lt;code&gt;code&lt;&#x2F;code&gt;, thus a contract cannot be destroyed and recreated within one transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h3&gt;
&lt;p&gt;Example 0&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 1&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0xdeadbeef00000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 2&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0xdeadbeef00000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x000000000000000000000000feed000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0xD04116cDd17beBE565EB2422F2497E06cC1C9833&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 3&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0xdeadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 4&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0x00000000000000000000000000000000deadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x00000000000000000000000000000000000000000000000000000000cafebabe&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0xdeadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32006&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0x60f3f640a8508fC6a86d45DF051962668E1e8AC7&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 5&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0x00000000000000000000000000000000deadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x00000000000000000000000000000000000000000000000000000000cafebabe&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32012&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Example 6&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;address &lt;code&gt;0x0000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;salt &lt;code&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;init_code &lt;code&gt;0x&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;gas (assuming no mem expansion): &lt;code&gt;32000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;result: &lt;code&gt;0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>tokenURI Interoperability</title>
        <published>2018-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Tommy Nicholas</name><uri>https://github.com/tomasienrbc</uri>
	</author>
	
	<author>
		<name>Matt Russo</name><uri>https://github.com/mateosu</uri>
	</author>
	
	<author>
		<name>John Zettler</name><uri>https://github.com/JohnZettler</uri>
	</author>
	
	<author>
		<name>Matt Condon</name><uri>https://github.com/shrugs</uri>
	</author>
	
	<author>
		<name>Gavin John</name><uri>https://github.com/Pandapip1</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/1046/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-1046-erc-20-metadata-extension/13036" />
        

        <id>https://wg-eips.ritovision.com/1046/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:1046"
            label="ERC-1046" />
        

        
        

        
        <summary type="html">Extends ERC-20 with an ERC-721-like tokenURI, and extends ERC-721 and ERC-1155 with interoperability</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/1046/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; introduced a &lt;code&gt;tokenURI&lt;&#x2F;code&gt; function for non-fungible tokens to handle miscellaneous metadata such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;thumbnail image&lt;&#x2F;li&gt;
&lt;li&gt;title&lt;&#x2F;li&gt;
&lt;li&gt;description&lt;&#x2F;li&gt;
&lt;li&gt;special asset properties&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This ERC adds a &lt;code&gt;tokenURI&lt;&#x2F;code&gt; function to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, and extends &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt; to enable interoperability between all three types of token URI.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;See the note about the metadata extension in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;#rationale&quot;&gt;ERC-721&lt;&#x2F;a&gt;. The same arguments apply to ERC-20.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to use similar mechanisms to extract metadata for ERC-20, ERC-721, ERC-1155, and future standards is useful for determining:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What type of token a contract is (if any);&lt;&#x2F;li&gt;
&lt;li&gt;How to display a token to a user, either in an asset listing page or on a dedicated token page; and&lt;&#x2F;li&gt;
&lt;li&gt;Determining the capabilities of the token&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interoperability-metadata&quot;&gt;Interoperability Metadata&lt;&#x2F;h3&gt;
&lt;p&gt;The following TypeScript interface is used in later sections:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Interoperability metadata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * This can be extended by other proposals.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * All fields MUST be optional.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * **Not every field has to be a boolean.** Any optional JSON-serializable object can be used by extensions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InteroperabilityMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This MUST be true if this is ERC-1046 Token Metadata, otherwise, this MUST be omitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Setting this to true indicates to wallets that the address should be treated as an ERC-20 token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    erc1046&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; undefined&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This MUST be true if this is ERC-721 Token Metadata, otherwise, this MUST be omitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Setting this to true indicates to wallets that the address should be treated as an ERC-721 token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    erc721&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; undefined&lt;&#x2F;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This MUST be true if this is ERC-1155 Token Metadata, otherwise, this MUST be omitted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Setting this to true indicates to wallets that the address should be treated as an ERC-1155 token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    erc1155&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; undefined&lt;&#x2F;span&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;h3 id=&quot;erc-20-extension&quot;&gt;ERC-20 Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc-20-interface-extension&quot;&gt;ERC-20 Interface Extension&lt;&#x2F;h4&gt;
&lt;p&gt;Compliant contracts MUST implement the following Solidity interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  ERC-20 Metadata Extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20TokenMetadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC20 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     Gets an ERC-721-like token URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;        The resolved data MUST be in JSON format and support ERC-1046&amp;#39;s ERC-20 Token Metadata Schema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;erc-20-token-metadata-schema&quot;&gt;ERC-20 Token Metadata Schema&lt;&#x2F;h4&gt;
&lt;p&gt;The resolved JSON of the &lt;code&gt;tokenURI&lt;&#x2F;code&gt; described in the ERC-20 Interface Extension section MUST conform to the following TypeScript interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Asset Metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20TokenMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Interoperability, to differentiate between different types of tokens and their corresponding URIs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    interop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InteroperabilityMetadata&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The name of the ERC-20 token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If the `name()` function is present in the ERC-20 token and returns a nonempty string, these MUST be the same value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The symbol of the ERC-20 token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If the `symbol()` function is present in the ERC-20 token and returns a nonempty string, these MUST be the same value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    symbol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The decimals of the ERC-20 token. &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If the `decimals()` function is present in the ERC-20 token, these MUST be the same value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Defaults to 18 if neither this parameter nor the ERC-20 `decimals()` function are present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    decimals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; number&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Provides a short one-paragraph description of the ERC-20 token, without any markup or newlines.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    description&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * A URI pointing to a resource with mime type `image&#x2F;*` that represents this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If the image is a bitmap, it SHOULD have a width between 320 and 1080 pixels&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * The image SHOULD have an aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * One or more URIs each pointing to a resource with mime type `image&#x2F;*` that represents this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Images SHOULD have an aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    images&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * One or more URIs each pointing to a resource with mime type `image&#x2F;*` that represent an icon for this token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels, and MUST have a height equal to its width&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Images MUST have an aspect ratio of 1:1, and use a transparent background&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    icons&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;erc-721-extension&quot;&gt;ERC-721 Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;extension-to-the-erc-721-metadata-schema&quot;&gt;Extension to the ERC-721 Metadata Schema&lt;&#x2F;h4&gt;
&lt;p&gt;Contracts that implement ERC-721 and use its token metadata URI SHOULD to use the following TypeScript extension to the metadata URI:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721TokenMetadataInterop&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; ERC721TokenMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Interoperability, to avoid confusion between different token URIs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    interop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InteroperabilityMetadata&lt;&#x2F;span&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;h3 id=&quot;erc-1155-extension&quot;&gt;ERC-1155 Extension&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;erc-1155-interface-extension&quot;&gt;ERC-1155 Interface Extension&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1155&#x2F;&quot;&gt;ERC-1155&lt;&#x2F;a&gt;-compliant contracts using the metadata extension SHOULD implement the following Solidity interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  ERC-1155 Metadata URI Interoperability Extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155TokenMetadataInterop&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC1155 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         Gets an ERC-1046-compliant ERC-1155 token URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The token ID to get the URI of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;            The resolved data MUST be in JSON format and support ERC-1046&amp;#39;s Extension to the ERC-1155 Token Metadata Schema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 This MUST be the same URI as the `uri(tokenId)` function, if present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;extension-to-the-erc-1155-metadata-schema&quot;&gt;Extension to the ERC-1155 Metadata Schema&lt;&#x2F;h4&gt;
&lt;p&gt;Contracts that implement ERC-1155 and use its token metadata URI are RECOMMENDED to use the following extension to the metadata URI. Contracts that implement the interface described in the ERC-1155 Interface Extension section MUST use the following TypeScript extension:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC1155TokenMetadataInterop&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity&quot;&gt; ERC1155TokenMetadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Interoperability, to avoid confusion between different token URIs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    interop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InteroperabilityMetadata&lt;&#x2F;span&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;h3 id=&quot;miscellaneous-recommendations&quot;&gt;Miscellaneous Recommendations&lt;&#x2F;h3&gt;
&lt;p&gt;To save gas, it is RECOMMENDED for compliant contracts not to implement the &lt;code&gt;name()&lt;&#x2F;code&gt;, &lt;code&gt;symbol()&lt;&#x2F;code&gt;, or &lt;code&gt;decimals()&lt;&#x2F;code&gt; functions, and instead to only include them in the metadata URI. Additionally, for ERC-20 tokens, if the decimals is &lt;code&gt;18&lt;&#x2F;code&gt;, then it is NOT RECOMMENDED to include the &lt;code&gt;decimals&lt;&#x2F;code&gt; field in the metadata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC makes adding metadata to ERC-20 tokens more straightforward for developers, with minimal to no disruption to the overall ecosystem. Using the same parameter name makes it easier to reuse code.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the recommendations not to use ERC-20&#x27;s &lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;symbol&lt;&#x2F;code&gt;, and &lt;code&gt;decimals&lt;&#x2F;code&gt; functions save gas.&lt;&#x2F;p&gt;
&lt;p&gt;Built-in interoperability is useful as otherwise it might not be easy to differentiate the type of the token. Interoperability could be done using &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, but static calls are time-inefficient for wallets and websites, and is generally inflexible. Instead, including interoperability data in the token URI increases flexibility while also giving a performance increase.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is fully backwards compatible as its implementation simply extends the functionality of ERC-20 tokens and is optional. Additionally, it makes backward compatible recommendations for ERC-721 and ERC-1155 tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;server-side-request-forgery-ssrf&quot;&gt;Server-Side Request Forgery (SSRF)&lt;&#x2F;h3&gt;
&lt;p&gt;Wallets should be careful about making arbitrary requests to URLs. As such, it is recommended for wallets to sanitize the URI by whitelisting specific schemes and ports. A vulnerable wallet could be tricked into, for example, modifying data on a locally-hosted redis database.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Node Discovery v4 ENR Extension</title>
        <published>2018-02-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Felix Lange</name><email>fjl@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/868/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/devp2p/issues/44" />
        

        <id>https://wg-eips.ritovision.com/868/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:868"
            label="EIP-868" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/868/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This EIP defines an extension to Node Discovery Protocol v4 to enable authoritative
resolution of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;778&#x2F;&quot;&gt;Ethereum Node Records (ENR)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;To bridge current and future discovery networks and to aid the implementation of other
relay mechanisms for ENR such as DNS, we need a way to request the most up-to-date version
of a node record. This EIP provides a way to request it using the existing discovery
protocol.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;Implementations of Node Discovery Protocol v4 should support two new packet types, a
request and reply of the node record. The existing ping and pong packets are extended with
a new field containing the sequence number of the ENR.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ping-packet-0x01&quot;&gt;Ping Packet (0x01)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packet-data = [version, from, to, expiration, enr-seq]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;enr-seq&lt;&#x2F;code&gt; is the current sequence number of the sending node&#x27;s record. All other fields
retain their existing meaning.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pong-packet-0x02&quot;&gt;Pong Packet (0x02)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packet-data = [to, ping-hash, expiration, enr-seq]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;enr-seq&lt;&#x2F;code&gt; is the current sequence number of the sending node&#x27;s record. All other fields
retain their existing meaning.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enrrequest-packet-0x05&quot;&gt;ENRRequest Packet (0x05)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packet-data = [ expiration ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When a packet of this type is received, the node should reply with an ENRResponse packet
containing the current version of its record.&lt;&#x2F;p&gt;
&lt;p&gt;To guard against amplification attacks, the sender of ENRRequest should have replied to a
ping packet recently (just like for FindNode). The &lt;code&gt;expiration&lt;&#x2F;code&gt; field, a UNIX timestamp,
should be handled as for all other existing packets i.e. no reply should be sent if it
refers to a time in the past.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enrresponse-packet-0x06&quot;&gt;ENRResponse Packet (0x06)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packet-data = [ request-hash, ENR ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This packet is the response to ENRRequest.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;request-hash&lt;&#x2F;code&gt; is the hash of the entire ENRRequest packet being replied to.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ENR&lt;&#x2F;code&gt; is the node record.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The recipient of the packet should verify that the node record is signed by node who sent
ENRResponse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolving-records&quot;&gt;Resolving Records&lt;&#x2F;h2&gt;
&lt;p&gt;To resolve the current record of a node public key, perform a recursive Kademlia lookup
using the FindNode, Neighbors packets. When the node is found, send ENRRequest to it and
return the record from the response.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h1&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Non-Fungible Token Standard</title>
        <published>2018-01-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>William Entriken</name><uri>https://github.com/fulldecent</uri>
	</author>
	
	<author>
		<name>Dieter Shirley</name><email>dete@axiomzen.co</email>
	</author>
	
	<author>
		<name>Jacob Evans</name><email>jacob@dekz.net</email>
	</author>
	
	<author>
		<name>Nastassia Sachs</name><email>nastassia.sachs@protonmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/721/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/eips/issues/721" />
        

        <id>https://wg-eips.ritovision.com/721/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:721"
            label="ERC-721" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/721/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for non-fungible tokens, also known as deeds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard allows for the implementation of a standard API for NFTs within smart contracts. This standard provides basic functionality to track and transfer NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;We considered use cases of NFTs being owned and transacted by individuals as well as consignment to third party brokers&#x2F;wallets&#x2F;auctioneers (&quot;operators&quot;). NFTs can represent ownership over digital or physical assets. We considered a diverse universe of assets, and we know you will dream up many more:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Physical property — houses, unique artwork&lt;&#x2F;li&gt;
&lt;li&gt;Virtual collectibles — unique pictures of kittens, collectible cards&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Negative value&quot; assets — loans, burdens and other responsibilities&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In general, all houses are distinct and no two kittens are alike. NFTs are &lt;em&gt;distinguishable&lt;&#x2F;em&gt; and you must track the ownership of each one separately.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface allows wallet&#x2F;broker&#x2F;auction applications to work with any NFT on Ethereum. We provide for simple ERC-721 smart contracts as well as contracts that track an &lt;em&gt;arbitrarily large&lt;&#x2F;em&gt; number of NFTs. Additional applications are discussed below.&lt;&#x2F;p&gt;
&lt;p&gt;This standard is inspired by the ERC-20 token standard and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible).&lt;&#x2F;p&gt;
&lt;p&gt;Differences between this standard and EIP-20 are examined below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Every ERC-721 compliant contract must implement the &lt;code&gt;ERC721&lt;&#x2F;code&gt; and &lt;code&gt;ERC165&lt;&#x2F;code&gt; interfaces&lt;&#x2F;strong&gt; (subject to &quot;caveats&quot; below):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-721 Non-Fungible Token Standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x80ac58cd.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC165 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when ownership of any NFT changes by any mechanism.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  This event emits when NFTs are created (`from` == 0) and destroyed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  (`to` == 0). Exception: during contract creation, any number of NFTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  may be created and assigned without emitting Transfer. At the time of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  any transfer, the approved address for that NFT (if any) is reset to none.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when the approved address for an NFT is &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  reaffirmed. The zero address indicates there is no approved address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  When a Transfer event emits, this also indicates that the approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  address for that NFT (if any) is reset to none.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This emits when an operator is enabled or disabled for an owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  The operator can manage all NFTs of the owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Count all NFTs assigned to an owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFTs assigned to the zero address are considered invalid, and this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  function throws for queries about the zero address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An address for whom to query the balance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; number of NFTs owned by `_owner`, possibly zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find the owner of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; NFTs assigned to zero address are considered invalid, and queries&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  about them do throw.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The identifier for an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers the ownership of an NFT from one address to another address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws unless `msg.sender` is the current owner, an authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  operator, or the approved address for this NFT. Throws if `_from` is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  not the current owner. Throws if `_to` is the zero address. Throws if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `_tokenId` is not a valid NFT. When transfer is complete, this function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  checks if `_to` is a smart contract (code size &amp;gt; 0). If so, it calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `onERC721Received` on `_to` and throws if the return value is not&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `bytes4(keccak256(&amp;quot;onERC721Received(address,address,uint256,bytes)&amp;quot;))`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The current owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format, sent in call to `_to`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfers the ownership of an NFT from one address to another address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This works identically to the other function with an extra data parameter,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  except this function just sets data to &amp;quot;&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The current owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  THEY MAY BE PERMANENTLY LOST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws unless `msg.sender` is the current owner, an authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  operator, or the approved address for this NFT. Throws if `_from` is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  not the current owner. Throws if `_to` is the zero address. Throws if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `_tokenId` is not a valid NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The current owner of the NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Change or reaffirm the approved address for an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The zero address indicates there is no approved address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Throws unless `msg.sender` is the current NFT owner, or an authorized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  operator of the current owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new approved NFT controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to approve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enable or disable approval for a third party (&amp;quot;operator&amp;quot;) to manage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  all of `msg.sender`&amp;#39;s assets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Emits the ApprovalForAll event. The contract MUST allow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  multiple operators per owner.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to add to the set of authorized operators&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True if the operator is approved, false to revoke approval&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the approved address for a single NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_tokenId` is not a valid NFT.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT to find the approved address for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; approved address for this NFT, or the zero address if there is none&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if an address is an authorized operator for another address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that owns the NFTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address that acts on behalf of the owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if `_operator` is an approved operator for `_owner`, false otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if a contract implements an interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface identifier, as specified in ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface identification is specified in ERC-165. This function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  uses less than 30,000 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if the contract implements `interfaceID` and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `interfaceID` is not 0xffffffff, `false` otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A wallet&#x2F;broker&#x2F;auction application MUST implement the &lt;strong&gt;wallet interface&lt;&#x2F;strong&gt; if it will accept safe transfers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x150b7a02.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721TokenReceiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Handle the receipt of an NFT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The ERC721 smart contract calls this function on the recipient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  after a `transfer`. This function MAY throw to revert and reject the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  transfer. Return of other than the magic value MUST result in the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  transaction being reverted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the contract address is always the message sender.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address which called `safeTransferFrom` function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The address which previously owned the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The NFT identifier which is being transferred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Additional data with no specified format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `bytes4(keccak256(&amp;quot;onERC721Received(address,address,uint256,bytes)&amp;quot;))`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  unless throwing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; onERC721Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;metadata extension&lt;&#x2F;strong&gt; is OPTIONAL for ERC-721 smart contracts (see &quot;caveats&quot;, below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-721 Non-Fungible Token Standard, optional metadata extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x5b5e139f.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A descriptive name for a collection of NFTs in this contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An abbreviated name for NFTs in this contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A distinct Uniform Resource Identifier (URI) for a given asset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  3986. The URI may point to a JSON file that conforms to the &amp;quot;ERC721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Metadata JSON Schema&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the &quot;ERC721 Metadata JSON Schema&quot; referenced above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Asset Metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Identifies the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Describes the asset to which this NFT represents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;image&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;description&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A URI pointing to a resource with mime type image&#x2F;* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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 &lt;strong&gt;enumeration extension&lt;&#x2F;strong&gt; is OPTIONAL for ERC-721 smart contracts (see &quot;caveats&quot;, below). This allows your contract to publish its full list of NFTs and make them discoverable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC-721 Non-Fungible Token Standard, optional enumeration extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;  Note&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: the ERC-165 identifier for this interface is 0x780e9d63.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC721Enumerable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is ERC721 &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Count NFTs tracked by this contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; count of valid NFTs tracked by this contract, where each one of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  them has an assigned and queryable owner not equal to the zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enumerate valid NFTs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_index` &amp;gt;= `totalSupply()`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A counter less than `totalSupply()`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token identifier for the `_index`th NFT,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  (sort order not specified)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Enumerate NFTs assigned to an owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Throws if `_index` &amp;gt;= `balanceOf(_owner)` or if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `_owner` is the zero address, representing invalid NFTs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An address where we are interested in NFTs owned by them&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; A counter less than `balanceOf(_owner)`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; token identifier for the `_index`th NFT assigned to `_owner`,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   (sort order not specified)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenOfOwnerByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h3&gt;
&lt;p&gt;The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 standard. A contract which complies with ERC-721 MUST also abide by the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Solidity issue #3412: The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: &lt;code&gt;payable&lt;&#x2F;code&gt;, implicit nonpayable, &lt;code&gt;view&lt;&#x2F;code&gt;, and &lt;code&gt;pure&lt;&#x2F;code&gt;. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a &lt;code&gt;payable&lt;&#x2F;code&gt; function in this interface may be implemented as nonpayable (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract.&lt;&#x2F;li&gt;
&lt;li&gt;Solidity issue #3419: A contract that implements &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt; or &lt;code&gt;ERC721Enumerable&lt;&#x2F;code&gt; SHALL also implement &lt;code&gt;ERC721&lt;&#x2F;code&gt;. ERC-721 implements the requirements of interface ERC-165.&lt;&#x2F;li&gt;
&lt;li&gt;Solidity issue #2330: If a function is shown in this specification as &lt;code&gt;external&lt;&#x2F;code&gt; then a contract will be compliant if it uses &lt;code&gt;public&lt;&#x2F;code&gt; visibility. As a workaround for version 0.4.20, you can edit this interface to switch to &lt;code&gt;public&lt;&#x2F;code&gt; before inheriting from your contract.&lt;&#x2F;li&gt;
&lt;li&gt;Solidity issues #3494, #3544: Use of &lt;code&gt;this.*.selector&lt;&#x2F;code&gt; is marked as a warning by Solidity, a future version of Solidity will not mark this as an error.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;There are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in Decentraland, the eponymous punks in CryptoPunks, and in-game items using systems like DMarket or EnjinCoin. Future uses include tracking real-world assets, like real-estate (as envisioned by companies like Ubitquity or Propy). It is critical in each of these cases that these items are not &quot;lumped together&quot; as numbers in a ledger, but instead each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;NFT&quot; Word Choice&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;NFT&quot; was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recognize that &quot;deed&quot; is very descriptive for certain applications of this standard (notably, physical property).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Alternatives considered: distinguishable asset, title, token, asset, equity, ticket&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NFT Identifiers&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Every NFT is identified by a unique &lt;code&gt;uint256&lt;&#x2F;code&gt; ID inside the ERC-721 smart contract. This identifying number SHALL NOT change for the life of the contract. The pair &lt;code&gt;(contract address, uint256 tokenId)&lt;&#x2F;code&gt; will then be a globally unique and fully-qualified identifier for a specific asset on an Ethereum chain. While some ERC-721 smart contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a &quot;black box&quot;. Also note that NFTs MAY become invalid (be destroyed). Please see the enumeration functions for a supported enumeration interface.&lt;&#x2F;p&gt;
&lt;p&gt;The choice of &lt;code&gt;uint256&lt;&#x2F;code&gt; allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to &lt;code&gt;uint256&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Transfer Mechanism&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ERC-721 standardizes a safe transfer function &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt; (overloaded with and without a &lt;code&gt;bytes&lt;&#x2F;code&gt; parameter) and an unsafe function &lt;code&gt;transferFrom&lt;&#x2F;code&gt;. Transfers may be initiated by:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The owner of an NFT&lt;&#x2F;li&gt;
&lt;li&gt;The approved address of an NFT&lt;&#x2F;li&gt;
&lt;li&gt;An authorized operator of the current owner of an NFT&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, an authorized operator may set the approved address for an NFT. This provides a powerful set of tools for wallet, broker and auction applications to quickly use a &lt;em&gt;large&lt;&#x2F;em&gt; number of NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;The transfer and accept functions&#x27; documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Disallow transfers if the contract is paused&lt;&#x2F;strong&gt; — prior art, CryptoKitties deployed contract, line 611&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Blocklist certain address from receiving NFTs&lt;&#x2F;strong&gt; — prior art, CryptoKitties deployed contract, lines 565, 566&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Disallow unsafe transfers&lt;&#x2F;strong&gt; — &lt;code&gt;transferFrom&lt;&#x2F;code&gt; throws unless &lt;code&gt;_to&lt;&#x2F;code&gt; equals &lt;code&gt;msg.sender&lt;&#x2F;code&gt; or &lt;code&gt;countOf(_to)&lt;&#x2F;code&gt; is non-zero or was non-zero previously (because such cases are safe)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Charge a fee to both parties of a transaction&lt;&#x2F;strong&gt; — require payment when calling &lt;code&gt;approve&lt;&#x2F;code&gt; with a non-zero &lt;code&gt;_approved&lt;&#x2F;code&gt; if it was previously the zero address, refund payment if calling &lt;code&gt;approve&lt;&#x2F;code&gt; with the zero address if it was previously a non-zero address, require payment when calling any transfer function, require transfer parameter &lt;code&gt;_to&lt;&#x2F;code&gt; to equal &lt;code&gt;msg.sender&lt;&#x2F;code&gt;, require transfer parameter &lt;code&gt;_to&lt;&#x2F;code&gt; to be the approved address for the NFT&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Read only NFT registry&lt;&#x2F;strong&gt; — always throw from &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;, &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Failed transactions will throw, a best practice identified in ERC-223, ERC-677, ERC-827 and OpenZeppelin&#x27;s implementation of SafeERC20.sol. ERC-20 defined an &lt;code&gt;allowance&lt;&#x2F;code&gt; feature, this caused a problem when called and then later modified to a different amount, as on OpenZeppelin issue #438. In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20&#x27;s original design without problems that have been later discovered.&lt;&#x2F;p&gt;
&lt;p&gt;Creation of NFTs (&quot;minting&quot;) and destruction of NFTs (&quot;burning&quot;) is not included in the specification. Your contract may implement these by other means. Please see the &lt;code&gt;event&lt;&#x2F;code&gt; documentation for your responsibilities when creating or destroying NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;We questioned if the &lt;code&gt;operator&lt;&#x2F;code&gt; parameter on &lt;code&gt;onERC721Received&lt;&#x2F;code&gt; was necessary. In all cases we could imagine, if the operator was important then that operator could transfer the token to themself and then send it -- then they would be the &lt;code&gt;from&lt;&#x2F;code&gt; address. This seems contrived because we consider the operator to be a temporary owner of the token (and transferring to themself is redundant). When the operator sends the token, it is the operator acting on their own accord, NOT the operator acting on behalf of the token holder. This is why the operator and the previous token owner are both significant to the token recipient.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Alternatives considered: only allow two-step ERC-20 style transaction, require that transfer functions never throw, require all functions to return a boolean indicating the success of the operation.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;ERC-165 Interface&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We chose Standard Interface Detection (ERC-165) to expose the interfaces that a ERC-721 smart contract supports.&lt;&#x2F;p&gt;
&lt;p&gt;A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your ERC-721 implementation to implement &lt;code&gt;ERC721Enumerable&lt;&#x2F;code&gt;, &lt;code&gt;ERC721Metadata&lt;&#x2F;code&gt;, or other interfaces by delegating to a separate contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Gas and Complexity&lt;&#x2F;strong&gt; (regarding the enumeration extension)&lt;&#x2F;p&gt;
&lt;p&gt;This specification contemplates implementations that manage a few and &lt;em&gt;arbitrarily large&lt;&#x2F;em&gt; numbers of NFTs. If your application is able to grow then avoid using for&#x2F;while loops in your code (see CryptoKitties bounty issue #4). These indicate your contract may be unable to scale and gas costs will rise over time without bound.&lt;&#x2F;p&gt;
&lt;p&gt;We have deployed a contract, XXXXERC721, to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That&#x27;s enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than querying the ENS.&lt;&#x2F;p&gt;
&lt;p&gt;This illustration makes clear: the ERC-721 standard scales.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Alternatives considered: remove the asset enumeration function if it requires a for-loop, return a Solidity array type from enumeration functions.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Privacy&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Wallets&#x2F;brokers&#x2F;auctioneers identified in the motivation section have a strong need to identify which NFTs an owner owns.&lt;&#x2F;p&gt;
&lt;p&gt;It may be interesting to consider a use case where NFTs are not enumerable, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call &lt;code&gt;ownerOf&lt;&#x2F;code&gt; for every possible &lt;code&gt;tokenId&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Metadata Choices&lt;&#x2F;strong&gt; (metadata extension)&lt;&#x2F;p&gt;
&lt;p&gt;We have required &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; functions in the metadata extension. Every token EIP and draft we reviewed (ERC-20, ERC-223, ERC-677, ERC-777, ERC-827) included these functions.&lt;&#x2F;p&gt;
&lt;p&gt;We remind implementation authors that the empty string is a valid response to &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; if you protest to the usage of this mechanism. We also remind everyone that any smart contract can use the same name and symbol as &lt;em&gt;your&lt;&#x2F;em&gt; contract. How a client may determine which ERC-721 smart contracts are well-known (canonical) is outside the scope of this standard.&lt;&#x2F;p&gt;
&lt;p&gt;A mechanism is provided to associate NFTs with URIs. We expect that many implementations will take advantage of this to provide metadata for each NFT. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered an NFT representing ownership of a house, in this case metadata about the house (image, occupants, etc.) can naturally change.&lt;&#x2F;p&gt;
&lt;p&gt;Metadata is returned as a string value. Currently this is only usable as calling from &lt;code&gt;web3&lt;&#x2F;code&gt;, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Alternatives considered: put all metadata for each asset on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), multiaddr network address (not mature enough)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Community Consensus&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A significant amount of discussion occurred on the original ERC-721 issue, additionally we held a first live meeting on Gitter that had good representation and well advertised (on Reddit, in the Gitter #ERC channel, and the original ERC-721 issue). Thank you to the participants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;imallinnow&quot;&gt;@ImAllInNow&lt;&#x2F;a&gt; Rob from DEC Gaming &#x2F; Presenting Michigan Ethereum Meetup Feb 7&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arachnid&quot;&gt;@Arachnid&lt;&#x2F;a&gt; Nick Johnson&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jadhavajay&quot;&gt;@jadhavajay&lt;&#x2F;a&gt; Ajay Jadhav from AyanWorks&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;superphly&quot;&gt;@superphly&lt;&#x2F;a&gt; Cody Marx Bailey - XRAM Capital &#x2F; Sharing at hackathon Jan 20 &#x2F; UN Future of Finance Hackathon.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fulldecent&quot;&gt;@fulldecent&lt;&#x2F;a&gt; William Entriken&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A second event was held at ETHDenver 2018 to discuss distinguishable asset standards (notes to be published).&lt;&#x2F;p&gt;
&lt;p&gt;We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;We have adopted &lt;code&gt;balanceOf&lt;&#x2F;code&gt;, &lt;code&gt;totalSupply&lt;&#x2F;code&gt;, &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;symbol&lt;&#x2F;code&gt; semantics from the ERC-20 specification. An implementation may also include a function &lt;code&gt;decimals&lt;&#x2F;code&gt; that returns &lt;code&gt;uint8(0)&lt;&#x2F;code&gt; if its goal is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the &lt;code&gt;decimals&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;Example NFT implementations as of February 2018:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CryptoKitties -- Compatible with an earlier version of this standard.&lt;&#x2F;li&gt;
&lt;li&gt;CryptoPunks -- Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the assets as &quot;punks&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Auctionhouse Asset Interface -- The author needed a generic interface for the Auctionhouse ÐApp (currently ice-boxed). His &quot;Asset&quot; contract is very simple, but is missing ERC-20 compatibility, &lt;code&gt;approve()&lt;&#x2F;code&gt; functionality, and metadata. This effort is referenced in the discussion for EIP-173.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note: &quot;Limited edition, collectible tokens&quot; like Curio Cards and Rare Pepe are &lt;em&gt;not&lt;&#x2F;em&gt; distinguishable assets. They&#x27;re actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be &lt;code&gt;1&lt;&#x2F;code&gt; in extreme cases).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;onERC721Received&lt;&#x2F;code&gt; function specifically works around old deployed contracts which may inadvertently return 1 (&lt;code&gt;true&lt;&#x2F;code&gt;) in certain circumstances even if they don&#x27;t implement a function (see Solidity DelegateCallReturnValue bug). By returning and checking for a magic value, we are able to distinguish actual affirmative responses versus these vacuous &lt;code&gt;true&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;0xcert ERC-721 Token includes test cases written using Truffle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementations&quot;&gt;Implementations&lt;&#x2F;h2&gt;
&lt;p&gt;0xcert ERC721 -- a reference implementation&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MIT licensed, so you can freely use it for your projects&lt;&#x2F;li&gt;
&lt;li&gt;Includes test cases&lt;&#x2F;li&gt;
&lt;li&gt;Active bug bounty, you will be paid if you find errors&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Su Squares -- an advertising platform where you can rent space and place images&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Complete the Su Squares Bug Bounty Program to seek problems with this standard or its implementation&lt;&#x2F;li&gt;
&lt;li&gt;Implements the complete standard and all optional interfaces&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;ERC721ExampleDeed -- an example implementation&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Implements using the OpenZeppelin project format&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;XXXXERC721, by William Entriken -- a scalable example implementation&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Deployed on testnet with 1 billion assets and supporting all lookups with the metadata extension. This demonstrates that scaling is NOT a problem.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Standards&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; Token Standard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Standard Interface Detection.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;173&#x2F;&quot;&gt;ERC-173&lt;&#x2F;a&gt; Owned Standard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;223&quot;&gt;ERC-223&lt;&#x2F;a&gt; Token Standard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;677&quot;&gt;ERC-677&lt;&#x2F;a&gt; &lt;code&gt;transferAndCall&lt;&#x2F;code&gt; Token Standard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;827&quot;&gt;ERC-827&lt;&#x2F;a&gt; Token Standard.&lt;&#x2F;li&gt;
&lt;li&gt;Ethereum Name Service (ENS). https:&#x2F;&#x2F;ens.domains&lt;&#x2F;li&gt;
&lt;li&gt;Instagram -- What&#x27;s the Image Resolution? https:&#x2F;&#x2F;help.instagram.com&#x2F;1631821640426723&lt;&#x2F;li&gt;
&lt;li&gt;JSON Schema. https:&#x2F;&#x2F;json-schema.org&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;Multiaddr. https:&#x2F;&#x2F;github.com&#x2F;multiformats&#x2F;multiaddr&lt;&#x2F;li&gt;
&lt;li&gt;RFC 2119 Key words for use in RFCs to Indicate Requirement Levels. https:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc2119.txt&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Issues&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The Original ERC-721 Issue. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;eips&#x2F;issues&#x2F;721&lt;&#x2F;li&gt;
&lt;li&gt;Solidity Issue #2330 -- Interface Functions are External. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;issues&#x2F;2330&lt;&#x2F;li&gt;
&lt;li&gt;Solidity Issue #3412 -- Implement Interface: Allow Stricter Mutability. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;issues&#x2F;3412&lt;&#x2F;li&gt;
&lt;li&gt;Solidity Issue #3419 -- Interfaces Can&#x27;t Inherit. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;issues&#x2F;3419&lt;&#x2F;li&gt;
&lt;li&gt;Solidity Issue #3494 -- Compiler Incorrectly Reasons About the &lt;code&gt;selector&lt;&#x2F;code&gt; Function. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;issues&#x2F;3494&lt;&#x2F;li&gt;
&lt;li&gt;Solidity Issue #3544 -- Cannot Calculate Selector of Function Named &lt;code&gt;transfer&lt;&#x2F;code&gt;. https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;issues&#x2F;3544&lt;&#x2F;li&gt;
&lt;li&gt;CryptoKitties Bounty Issue #4 -- Listing all Kitties Owned by a User is &lt;code&gt;O(n^2)&lt;&#x2F;code&gt;. https:&#x2F;&#x2F;github.com&#x2F;axiomzen&#x2F;cryptokitties-bounty&#x2F;issues&#x2F;4&lt;&#x2F;li&gt;
&lt;li&gt;OpenZeppelin Issue #438 -- Implementation of &lt;code&gt;approve&lt;&#x2F;code&gt; method violates ERC20 standard. https:&#x2F;&#x2F;github.com&#x2F;OpenZeppelin&#x2F;zeppelin-solidity&#x2F;issues&#x2F;438&lt;&#x2F;li&gt;
&lt;li&gt;Solidity DelegateCallReturnValue Bug. https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;develop&#x2F;bugs.html#DelegateCallReturnValue&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Discussions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reddit (announcement of first live discussion). https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;ethereum&#x2F;comments&#x2F;7r2ena&#x2F;friday_119_live_discussion_on_erc_nonfungible&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;Gitter #EIPs (announcement of first live discussion). https:&#x2F;&#x2F;gitter.im&#x2F;ethereum&#x2F;EIPs?at=5a5f823fb48e8c3566f0a5e7&lt;&#x2F;li&gt;
&lt;li&gt;ERC-721 (announcement of first live discussion). https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;eips&#x2F;issues&#x2F;721#issuecomment-358369377&lt;&#x2F;li&gt;
&lt;li&gt;ETHDenver 2018. https:&#x2F;&#x2F;ethdenver.com&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;NFT Implementations and Other Projects&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;CryptoKitties. https:&#x2F;&#x2F;www.cryptokitties.co&lt;&#x2F;li&gt;
&lt;li&gt;0xcert ERC-721 Token. https:&#x2F;&#x2F;github.com&#x2F;0xcert&#x2F;ethereum-erc721&lt;&#x2F;li&gt;
&lt;li&gt;Su Squares. https:&#x2F;&#x2F;tenthousandsu.com&lt;&#x2F;li&gt;
&lt;li&gt;Decentraland. https:&#x2F;&#x2F;decentraland.org&lt;&#x2F;li&gt;
&lt;li&gt;CryptoPunks. https:&#x2F;&#x2F;www.larvalabs.com&#x2F;cryptopunks&lt;&#x2F;li&gt;
&lt;li&gt;DMarket. https:&#x2F;&#x2F;www.dmarket.io&lt;&#x2F;li&gt;
&lt;li&gt;Enjin Coin. https:&#x2F;&#x2F;enjincoin.io&lt;&#x2F;li&gt;
&lt;li&gt;Ubitquity. https:&#x2F;&#x2F;www.ubitquity.io&lt;&#x2F;li&gt;
&lt;li&gt;Propy. https:&#x2F;&#x2F;tokensale.propy.com&lt;&#x2F;li&gt;
&lt;li&gt;CryptoKitties Deployed Contract. https:&#x2F;&#x2F;etherscan.io&#x2F;address&#x2F;0x06012c8cf97bead5deae237070f9587f8e7a266d#code&lt;&#x2F;li&gt;
&lt;li&gt;Su Squares Bug Bounty Program. https:&#x2F;&#x2F;github.com&#x2F;fulldecent&#x2F;su-squares-bounty&lt;&#x2F;li&gt;
&lt;li&gt;XXXXERC721. https:&#x2F;&#x2F;github.com&#x2F;fulldecent&#x2F;erc721-example&lt;&#x2F;li&gt;
&lt;li&gt;ERC721ExampleDeed. https:&#x2F;&#x2F;github.com&#x2F;nastassiasachs&#x2F;ERC721ExampleDeed&lt;&#x2F;li&gt;
&lt;li&gt;Curio Cards. https:&#x2F;&#x2F;mycuriocards.com&lt;&#x2F;li&gt;
&lt;li&gt;Rare Pepe. https:&#x2F;&#x2F;rarepepewallet.com&lt;&#x2F;li&gt;
&lt;li&gt;Auctionhouse Asset Interface. https:&#x2F;&#x2F;github.com&#x2F;dob&#x2F;auctionhouse&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;Asset.sol&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;.&#x2F;assets&#x2F;SafeERC20.sol&quot;&gt;OpenZeppelin &lt;code&gt;SafeERC20.sol&lt;&#x2F;code&gt; Implementation&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Standard Interface Detection</title>
        <published>2018-01-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Christian Reitwießner</name><email>chris@ethereum.org</email>
	</author>
	
	<author>
		<name>Nick Johnson</name><email>nick@ethereum.org</email>
	</author>
	
	<author>
		<name>Fabian Vogelsteller</name><email>fabian@lukso.network</email>
	</author>
	
	<author>
		<name>Jordi Baylina</name><email>jordi@baylina.cat</email>
	</author>
	
	<author>
		<name>Konrad Feldmeier</name><email>konrad.feldmeier@brainbot.com</email>
	</author>
	
	<author>
		<name>William Entriken</name><email>github.com@phor.net</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/165/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/165/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:165"
            label="ERC-165" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/165/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Creates a standard method to publish and detect what interfaces a smart contract implements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Herein, we standardize the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;How interfaces are identified&lt;&#x2F;li&gt;
&lt;li&gt;How a contract will publish the interfaces it implements&lt;&#x2F;li&gt;
&lt;li&gt;How to detect if a contract implements ERC-165&lt;&#x2F;li&gt;
&lt;li&gt;How to detect if a contract implements any given interface&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;For some &quot;standard interfaces&quot; like &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;the ERC-20 token interface&lt;&#x2F;a&gt;, it is sometimes useful to query whether a contract supports the interface and if yes, which version of the interface, in order to adapt the way in which the contract is to be interacted with. Specifically for ERC-20, a version identifier has already been proposed. This proposal standardizes the concept of interfaces and standardizes the identification (naming) of interfaces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;how-interfaces-are-identified&quot;&gt;How Interfaces are Identified&lt;&#x2F;h3&gt;
&lt;p&gt;For this standard, an &lt;em&gt;interface&lt;&#x2F;em&gt; is a set of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;develop&#x2F;abi-spec.html#function-selector&quot;&gt;function selectors as defined by the Ethereum ABI&lt;&#x2F;a&gt;. This a subset of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;develop&#x2F;abi-spec.html&quot;&gt;Solidity&#x27;s concept of interfaces&lt;&#x2F;a&gt; and the  &lt;code&gt;interface&lt;&#x2F;code&gt; keyword definition which also defines return types, mutability and events.&lt;&#x2F;p&gt;
&lt;p&gt;We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Solidity101&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hello&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; world&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Selector&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; calculateSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&gt;        Solidity101 i&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hello&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;world&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&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;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;Note: interfaces do not permit optional functions, therefore, the interface identity will not include them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-a-contract-will-publish-the-interfaces-it-implements&quot;&gt;How a Contract will Publish the Interfaces it Implements&lt;&#x2F;h3&gt;
&lt;p&gt;A contract that is compliant with ERC-165 shall implement the following interface (referred as &lt;code&gt;ERC165.sol&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if a contract implements an interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface identifier, as specified in ERC-165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Interface identification is specified in ERC-165. This function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  uses less than 30,000 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if the contract implements `interfaceID` and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  `interfaceID` is not 0xffffffff, `false` otherwise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interface identifier for this interface is &lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt;. You can calculate this by running &lt;code&gt;bytes4(keccak256(&#x27;supportsInterface(bytes4)&#x27;));&lt;&#x2F;code&gt; or using the &lt;code&gt;Selector&lt;&#x2F;code&gt; contract above.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore the implementing contract will have a &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function that returns:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;true&lt;&#x2F;code&gt; when &lt;code&gt;interfaceID&lt;&#x2F;code&gt; is &lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt; (EIP165 interface)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;false&lt;&#x2F;code&gt; when &lt;code&gt;interfaceID&lt;&#x2F;code&gt; is &lt;code&gt;0xffffffff&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;true&lt;&#x2F;code&gt; for any other &lt;code&gt;interfaceID&lt;&#x2F;code&gt; this contract implements&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;false&lt;&#x2F;code&gt; for any other &lt;code&gt;interfaceID&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This function must return a bool and use at most 30,000 gas.&lt;&#x2F;p&gt;
&lt;p&gt;Implementation note, there are several logical ways to implement this function. Please see the example implementations and the discussion on gas usage.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-detect-if-a-contract-implements-erc-165&quot;&gt;How to Detect if a Contract Implements ERC-165&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;The source contract makes a &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; to the destination address with input data: &lt;code&gt;0x01ffc9a701ffc9a700000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt; and gas 30,000. This corresponds to &lt;code&gt;contract.supportsInterface(0x01ffc9a7)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If the call fails or return false, the destination contract does not implement ERC-165.&lt;&#x2F;li&gt;
&lt;li&gt;If the call returns true, a second call is made with input data &lt;code&gt;0x01ffc9a7ffffffff00000000000000000000000000000000000000000000000000000000&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If the second call fails or returns true, the destination contract does not implement ERC-165.&lt;&#x2F;li&gt;
&lt;li&gt;Otherwise it implements ERC-165.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;how-to-detect-if-a-contract-implements-any-given-interface&quot;&gt;How to Detect if a Contract Implements any Given Interface&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;If you are not sure if the contract implements ERC-165, use the above procedure to confirm.&lt;&#x2F;li&gt;
&lt;li&gt;If it does not implement ERC-165, then you will have to see what methods it uses the old-fashioned way.&lt;&#x2F;li&gt;
&lt;li&gt;If it implements ERC-165 then just call &lt;code&gt;supportsInterface(interfaceID)&lt;&#x2F;code&gt; to determine if it implements an interface you can use.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;We tried to keep this specification as simple as possible. This implementation is also compatible with the current Solidity version.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The mechanism described above (with &lt;code&gt;0xffffffff&lt;&#x2F;code&gt;) should work with most of the contracts previous to this standard to determine that they do not implement ERC-165.&lt;&#x2F;p&gt;
&lt;p&gt;Also &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;the ENS&lt;&#x2F;a&gt; already implements this EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Following is a contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165Query&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; InvalidID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xffffffff&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; doesContractImplementInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; InvalidID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt; erc165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&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 class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x40&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find empty storage location using &amp;quot;free memory pointer&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;                mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; erc165ID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place signature at beginning of empty storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;                mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x04&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place first argument directly next to signature&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;                success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; staticcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                                    30000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;         &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 30k gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; To addr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are stored at location x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                                    0x24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are 36 bytes long&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Store output over input (saves space)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                                    0x20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Outputs are 32 bytes long&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;                result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Load the result&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;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;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;This approach uses a &lt;code&gt;view&lt;&#x2F;code&gt; function implementation of &lt;code&gt;supportsInterface&lt;&#x2F;code&gt;. The execution cost is 586 gas for any input. But contract initialization requires storing each interface (&lt;code&gt;SSTORE&lt;&#x2F;code&gt; is 20,000 gas). The &lt;code&gt;ERC165MappingImplementation&lt;&#x2F;code&gt; contract is generic and reusable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;ERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165MappingImplementation&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; You must not set element 0xffffffff to true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; supportedInterfaces&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165MappingImplementation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        supportedInterfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; supportedInterfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;interfaceID&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Simpson&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is2D&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; skinColor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Lisa&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165MappingImplementation&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Simpson&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Lisa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        supportedInterfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is2D&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;skinColor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is2D&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; skinColor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Following is a &lt;code&gt;pure&lt;&#x2F;code&gt; function implementation of &lt;code&gt;supportsInterface&lt;&#x2F;code&gt;. The worst-case execution cost is 236 gas, but increases linearly with a higher number of supported interfaces.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.4.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.&#x2F;ERC165.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Simpson&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is2D&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; skinColor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Homer&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Simpson&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is2D&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                         ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;skinColor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;selector&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Simpson&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; is2D&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; skinColor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With three or more supported interfaces (including ERC165 itself as a required supported interface), the mapping approach (in every case) costs less gas than the pure approach (at worst case).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;version-history&quot;&gt;Version history&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PR 1640, finalized 2019-01-23 -- This corrects the noThrowCall test case to use 36 bytes rather than the previous 32 bytes. The previous code was an error that still silently worked in Solidity 0.4.x but which was broken by new behavior introduced in Solidity 0.5.0. This change was discussed at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;pull&#x2F;1640&quot;&gt;#1640&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;EIP 165, finalized 2018-04-20 -- Original published version.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Pseudo-introspection Registry Contract</title>
        <published>2018-01-05T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Jordi Baylina</name><email>jordi@baylina.cat</email>
	</author>
	
	<author>
		<name>Jacques Dafflon</name><email>jacques@dafflon.tech</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/820/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/820" />
        

        <id>https://wg-eips.ritovision.com/820/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:820"
            label="ERC-820" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/820/">&lt;blockquote&gt;
&lt;p&gt;:information_source: &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; has superseded &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;.&lt;&#x2F;strong&gt; :information_source:&lt;br &#x2F;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; fixes the incompatibility in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; logic which was introduced by the Solidty 0.5 update.&lt;br &#x2F;&gt;
Have a look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-464109166&quot;&gt;official announcement&lt;&#x2F;a&gt;, and the comments about the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-452465748&quot;&gt;bug&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;820#issuecomment-454021564&quot;&gt;fix&lt;&#x2F;a&gt;.&lt;br &#x2F;&gt;
Apart from this fix, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; is functionally equivalent to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;:warning: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; MUST be used in lieu of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;. :warning:&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines a universal registry smart contract where any address (contract or regular account) can register which interface it supports and which smart contract is responsible for its implementation.&lt;&#x2F;p&gt;
&lt;p&gt;This standard keeps backward compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines a registry where smart contracts and regular accounts can publish which functionalities they implement---either directly or through a proxy contract.&lt;&#x2F;p&gt;
&lt;p&gt;Anyone can query this registry to ask if a specific address implements a given interface and which smart contract handles its implementation.&lt;&#x2F;p&gt;
&lt;p&gt;This registry MAY be deployed on any chain and shares the same address on all chains.&lt;&#x2F;p&gt;
&lt;p&gt;Interfaces with zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;) as the last 28 bytes are considered &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interfaces, and this registry SHALL forward the call to the contract to see if it implements the interface.&lt;&#x2F;p&gt;
&lt;p&gt;This contract also acts as an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache to reduce gas consumption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;There have been different approaches to define pseudo-introspection in Ethereum. The first is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; which has the limitation that it cannot be used by regular accounts. The second attempt is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;672&quot;&gt;ERC-672&lt;&#x2F;a&gt; which uses reverse &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt;. Using reverse &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt; has two issues. First, it is unnecessarily complicated, and second, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ens.domains&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt; is still a centralized contract controlled by a multisig. This multisig theoretically would be able to modify the system.&lt;&#x2F;p&gt;
&lt;p&gt;This standard is much simpler than &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;672&quot;&gt;ERC-672&lt;&#x2F;a&gt;, and it is &lt;em&gt;fully&lt;&#x2F;em&gt; decentralized.&lt;&#x2F;p&gt;
&lt;p&gt;This standard also provides a &lt;em&gt;unique&lt;&#x2F;em&gt; address for all chains. Thus solving the problem of resolving the correct registry address for different chains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;erc-820-registry-smart-contract&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; Registry Smart Contract&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is an exact copy of the code of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbaylina&#x2F;ERC820&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;ERC820Registry.sol&quot;&gt;ERC820 registry smart contract&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * This standard defines a universal registry smart contract where any address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * (contract or regular account) can register which interface it supports and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * which smart contract is responsible for its implementation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * Written in 2018 by Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * To the extent possible under law, the author(s) have dedicated all copyright&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * and related and neighboring rights to this software to the public domain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * worldwide. This software is distributed without any warranty.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * You should have received a copy of the CC0 Public Domain Dedication along&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * with this software. If not, see&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &amp;lt;https:&#x2F;&#x2F;creativecommons.org&#x2F;publicdomain&#x2F;zero&#x2F;1.0&#x2F;&amp;gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ███████╗██████╗  ██████╗ █████╗ ██████╗  ██████╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔════╝██╔══██╗██╔════╝██╔══██╗╚════██╗██╔═████╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    █████╗  ██████╔╝██║     ╚█████╔╝ █████╔╝██║██╔██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══╝  ██╔══██╗██║     ██╔══██╗██╔═══╝ ████╔╝██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ███████╗██║  ██║╚██████╗╚█████╔╝███████╗╚██████╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗   ██╗&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   ██████╔╝ ╚████╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══██╗  ╚██╔╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ██║  ██║   ██║&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *    ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.4.24&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IV is value needed to have a vanity address starting with `0x820`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IV: 9513&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 class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The interface a contract MUST implement if it is the implementer of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; some (other) interface for any address other than itself.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates whether the contract implements the interface `interfaceHash` for the address `addr` or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ERC820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only if the contract implements `interfaceHash` for the address `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @author&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This contract is the official implementation of the ERC820 Registry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For more details, see https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC820Registry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 Invalid ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; INVALID_ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xffffffff&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256(&amp;#39;supportsInterface(bytes4)&amp;#39;))`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Magic value which is returned if a contract implements an interface on behalf of some other address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC820_ACCEPT_MAGIC &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC820_ACCEPT_MAGIC&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; managers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; erc165Cached&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates a contract is the `implementer` of `interfaceHash` for `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; implementer&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates `newManager` is the address of the new manager for `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ManagerChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; newManager&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address being queried for the implementer of an interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; E.g., `web3.utils.keccak256(&amp;#39;ERC777Token&amp;#39;)`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; address of the contract which implements the interface `_interfaceHash` for `_addr`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; or `0x0` if `_addr` did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            bytes4&lt;&#x2F;span&gt;&lt;span&gt; erc165InterfaceHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; erc165InterfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the contract which implements a specific interface for an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Only the manager defined for that address can set it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address to define the interface for. (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; For example, `web3.utils.keccak256(&amp;#39;ERC777TokensRecipient&amp;#39;)` for the `ERC777TokensRecipient` interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Contract address implementing _interfaceHash for _addr.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not the manager&amp;quot;&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Must not be a ERC165 hash&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;_implementer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; _implementer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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 class=&quot;z-entity z-name&quot;&gt;                ERC820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_implementer&lt;&#x2F;span&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;span class=&quot;z-entity z-name&quot;&gt;canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; ERC820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;Does not implement the interface&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _implementer&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the `_newManager` as manager for the `_addr` address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The new manager will be able to call `setInterfaceImplementer` for `_addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the new manager for `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Not the manager&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;        managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _newManager &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; _addr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ManagerChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _newManager&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Get the manager of an address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which to return the manager.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; Address&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; of the manager for a given address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; By default the manager of an address is the same address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; managers&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_addr&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Name of the interface.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; The&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; --- ERC165 Related Functions --- &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; --- Developed in collaboration with William Entriken. --- &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;*&#x2F;&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateERC165Cache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;        interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; _contract &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        erc165Cached&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The result may be cached, if not a direct lookup is performed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;erc165Cached&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaces&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; _contract&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address of the contract to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ERC165 interface to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; INVALID_ID&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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&gt;        (&lt;&#x2F;span&gt;&lt;span&gt;success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The hash to check.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; `true` if the hash is a ERC165 interface (ending with 28 zeroes), `false` otherwise.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _interfaceHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make a call on a contract without throwing if the function does not exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; noThrowCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&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 class=&quot;z-storage z-type&quot;&gt;        internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; result&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes4&lt;&#x2F;span&gt;&lt;span&gt; erc165ID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ERC165ID&lt;&#x2F;span&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 class=&quot;z-keyword&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 class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x40&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;               &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Find empty storage location using &amp;quot;free memory pointer&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;                mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; erc165ID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place signature at beginning of empty storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;                mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x04&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Place first argument directly next to signature&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;                success &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; staticcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                    30000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                         &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 30k gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; To addr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are stored at location x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                    0x08&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                          &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Inputs are 8 bytes long&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                             &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Store output over input (saves space)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                    0x20&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                           &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Outputs are 32 bytes long&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&gt;                result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;                 &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Load the result&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;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;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;deployment-transaction&quot;&gt;Deployment Transaction&lt;&#x2F;h3&gt;
&lt;p&gt;Below is the raw transaction which MUST be used to deploy the smart contract on any chain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf90a2a8085174876e800830c35008080b909d7608060405234801561001057600080fd5b506109b7806100206000396000f30060806040526004361061008d5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166329965a1d81146100925780633d584063146100bf5780635df8122f146100fc57806365ba36c114610123578063a41e7d5114610155578063aabbb8ca14610183578063b7056765146101a7578063f712f3e8146101e9575b600080fd5b34801561009e57600080fd5b506100bd600160a060020a036004358116906024359060443516610217565b005b3480156100cb57600080fd5b506100e0600160a060020a0360043516610512565b60408051600160a060020a039092168252519081900360200190f35b34801561010857600080fd5b506100bd600160a060020a036004358116906024351661055e565b34801561012f57600080fd5b506101436004803560248101910135610655565b60408051918252519081900360200190f35b34801561016157600080fd5b506100bd600160a060020a0360043516600160e060020a0319602435166106e3565b34801561018f57600080fd5b506100e0600160a060020a036004351660243561076d565b3480156101b357600080fd5b506101d5600160a060020a0360043516600160e060020a0319602435166107e7565b604080519115158252519081900360200190f35b3480156101f557600080fd5b506101d5600160a060020a0360043516600160e060020a03196024351661089c565b6000600160a060020a0384161561022e5783610230565b335b90503361023c82610512565b600160a060020a03161461029a576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b6102a38361091c565b156102f8576040805160e560020a62461bcd02815260206004820152601960248201527f4d757374206e6f74206265206120455243313635206861736800000000000000604482015290519081900360640190fd5b600160a060020a038216158015906103195750600160a060020a0382163314155b156104a15760405160200180807f4552433832305f4143434550545f4d414749430000000000000000000000000081525060130190506040516020818303038152906040526040518082805190602001908083835b6020831061038d5780518252601f19909201916020918201910161036e565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f249cb3fa000000000000000000000000000000000000000000000000000000008352600483018a9052600160a060020a0388811660248501529451909650938816945063249cb3fa936044808401945091929091908290030181600087803b15801561042057600080fd5b505af1158015610434573d6000803e3d6000fd5b505050506040513d602081101561044a57600080fd5b5051146104a1576040805160e560020a62461bcd02815260206004820181905260248201527f446f6573206e6f7420696d706c656d656e742074686520696e74657266616365604482015290519081900360640190fd5b600160a060020a03818116600081815260208181526040808320888452909152808220805473ffffffffffffffffffffffffffffffffffffffff19169487169485179055518692917f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db15391a450505050565b600160a060020a03808216600090815260016020526040812054909116151561053c575080610559565b50600160a060020a03808216600090815260016020526040902054165b919050565b3361056883610512565b600160a060020a0316146105c6576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b81600160a060020a031681600160a060020a0316146105e557806105e8565b60005b600160a060020a03838116600081815260016020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169585169590951790945592519184169290917f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a43509190a35050565b60008282604051602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b602083106106ad5780518252601f19909201916020918201910161068e565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090505b92915050565b6106ed82826107e7565b6106f85760006106fa565b815b600160a060020a03928316600081815260208181526040808320600160e060020a031996909616808452958252808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181209281529190925220805460ff19166001179055565b60008080600160a060020a038516156107865784610788565b335b91506107938461091c565b156107b85750826107a4828261089c565b6107af5760006107b1565b815b92506107df565b600160a060020a038083166000908152602081815260408083208884529091529020541692505b505092915050565b60008080610815857f01ffc9a70000000000000000000000000000000000000000000000000000000061093e565b9092509050811580610825575080155b1561083357600092506107df565b61084585600160e060020a031961093e565b909250905081158061085657508015155b1561086457600092506107df565b61086e858561093e565b90925090506001821480156108835750806001145b1561089157600192506107df565b506000949350505050565b600160a060020a0382166000908152600260209081526040808320600160e060020a03198516845290915281205460ff1615156108e4576108dd83836107e7565b90506106dd565b50600160a060020a03808316600081815260208181526040808320600160e060020a0319871684529091529020549091161492915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6040517f01ffc9a7000000000000000000000000000000000000000000000000000000008082526004820183905260009182919060208160088189617530fa9051909690955093505050505600a165627a7a723058204fc4461c9d5a247b0eafe0f9c508057bc0ad72bc24668cb2a35ea65850e10d3100291ba08208208208208208208208208208208208208208208208208208208208208200a00820820820820820820820820820820820820820820820820820820820820820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The strings of &lt;code&gt;820&lt;&#x2F;code&gt;&#x27;s at the end of the transaction are the &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; of the signature. From this deterministic pattern (generated by a human), anyone can deduce that no one knows the private key for the deployment account.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deployment-method&quot;&gt;Deployment Method&lt;&#x2F;h3&gt;
&lt;p&gt;This contract is going to be deployed using the keyless deployment method---also known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Arachnid&#x2F;&quot;&gt;Nick&lt;&#x2F;a&gt;&#x27;s method---which relies on a single-use address. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@weka&#x2F;how-to-send-ether-to-11-440-people-187e332566b7&quot;&gt;Nick&#x27;s article&lt;&#x2F;a&gt; for more details). This method works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Generate a transaction which deploys the contract from a new random account.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;This transaction MUST NOT use &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; in order to work on any chain.&lt;&#x2F;li&gt;
&lt;li&gt;This transaction MUST have a relatively high gas price to be deployed on any chain. In this case, it is going to be 100 Gwei.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;Set the &lt;code&gt;v&lt;&#x2F;code&gt;, &lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; of the transaction signature to the following values:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;v: 27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;r: 0x8208208208208208208208208208208208208208208208208208208208208200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s: 0x0820820820820820820820820820820820820820820820820820820820820820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; values---made of a repeating pattern of &lt;code&gt;820&lt;&#x2F;code&gt;&#x27;s---are predictable &quot;random numbers&quot; generated deterministically by a human.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The values of &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; must be 32 bytes long each---or 64 characters in hexadecimal. Since &lt;code&gt;820&lt;&#x2F;code&gt; is 3 characters long and 3 is not a divisor of 64, but it is a divisor of 63, the &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; values are padded with one extra character.&lt;br &#x2F;&gt;
The &lt;code&gt;s&lt;&#x2F;code&gt; value is prefixed with a single zero (&lt;code&gt;0&lt;&#x2F;code&gt;). The &lt;code&gt;0&lt;&#x2F;code&gt; prefix also guarantees that &lt;code&gt;s &amp;lt; secp256k1n ÷ 2 + 1&lt;&#x2F;code&gt;.&lt;br &#x2F;&gt;
The &lt;code&gt;r&lt;&#x2F;code&gt; value, cannot be prefixed with a zero, as the transaction becomes invalid. Instead it is suffixed with a zero (&lt;code&gt;0&lt;&#x2F;code&gt;) which still respects the condition &lt;code&gt;s &amp;lt; secp256k1n&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We recover the sender of this transaction, i.e., the single-use deployment account.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thus we obtain an account that can broadcast that transaction, but we also have the warranty that nobody knows the private key of that account.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Send exactly 0.08 ethers to this single-use deployment account.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Broadcast the deployment transaction.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This operation can be done on any chain, guaranteeing that the contract address is always the same and nobody can use that address with a different contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;single-use-registry-deployment-account&quot;&gt;Single-use Registry Deployment Account&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xE6C244a1C10Aa0085b0cf92f04cdaD947C2988b8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This account is generated by reverse engineering it from its signature for the transaction. This way no one knows the private key, but it is known that it is the valid signer of the deployment transaction.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To deploy the registry, 0.08 ethers MUST be sent to this account &lt;em&gt;first&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;registry-contract-address&quot;&gt;Registry Contract Address&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x820b586C8C28125366C998641B09DCbE7d4cBF06&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The contract has the address above for every chain on which it is deployed.&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;Raw metadata of &lt;code&gt;.&#x2F;contracts&#x2F;ERC820Registry.sol&lt;&#x2F;code&gt;&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;compiler&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0.4.24+commit.e67f0147&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;language&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;output&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;getManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;setManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;updateERC165Cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nonpayable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementsERC165Interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;payable&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;stateMutability&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;view&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;anonymous&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;InterfaceImplementerSet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;anonymous&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ManagerChanged&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;devdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;author&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;methods&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getInterfaceImplementer(address,bytes32)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address being queried for the implementer of an interface. (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;keccak256 hash of the name of the interface as a string. E.g., `web3.utils.keccak256(&amp;#39;ERC777Token&amp;#39;)`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The address of the contract which implements the interface `_interfaceHash` for `_addr` or `0x0` if `_addr` did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getManager(address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address for which to return the manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the manager for a given address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165Interface(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;`true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165InterfaceNoCache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;`true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;interfaceHash(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceName&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Name of the interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setInterfaceImplementer(address,bytes32,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address to define the interface for. (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_implementer&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Contract address implementing _interfaceHash for _addr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;keccak256 hash of the name of the interface as a string. For example, `web3.utils.keccak256(&amp;#39;ERC777TokensRecipient&amp;#39;)` for the `ERC777TokensRecipient` interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setManager(address,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_newManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the new manager for `addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;updateERC165Cache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;_interfaceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;userdoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;methods&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getInterfaceImplementer(address,bytes32)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;getManager(address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Get the manager of an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165Interface(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Checks whether a contract implements an ERC165 interface or not. The result may be cached, if not a direct lookup is performed.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;implementsERC165InterfaceNoCache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;interfaceHash(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setInterfaceImplementer(address,bytes32,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sets the contract which implements a specific interface for an address. Only the manager defined for that address can set it. (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;setManager(address,address)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sets the `_newManager` as manager for the `_addr` address. The new manager will be able to call `setInterfaceImplementer` for `_addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;updateERC165Cache(address,bytes4)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;compilationTarget&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;.&#x2F;contracts&#x2F;ERC820Registry.sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC820Registry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;evmVersion&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;byzantium&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;libraries&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;optimizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;runs&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;remappings&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;sources&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;.&#x2F;contracts&#x2F;ERC820Registry.sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;* ERC820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * This standard defines a universal registry smart contract where any address&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * (contract or regular account) can register which interface it supports and&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * which smart contract is responsible for its implementation.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * Written in 2018 by Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * To the extent possible under law, the author(s) have dedicated all copyright&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * and related and neighboring rights to this software to the public domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * worldwide. This software is distributed without any warranty.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * You should have received a copy of the CC0 Public Domain Dedication along&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * with this software. If not, see&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; * &amp;lt;https:&#x2F;&#x2F;creativecommons.org&#x2F;publicdomain&#x2F;zero&#x2F;1.0&#x2F;&amp;gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ███████╗██████╗  ██████╗ █████╗ ██████╗  ██████╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔════╝██╔══██╗██╔════╝██╔══██╗╚════██╗██╔═████╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    █████╗  ██████╔╝██║     ╚█████╔╝ █████╔╝██║██╔██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══╝  ██╔══██╗██║     ██╔══██╗██╔═══╝ ████╔╝██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ███████╗██║  ██║╚██████╗╚█████╔╝███████╗╚██████╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗   ██╗&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   ██████╔╝ ╚████╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══██╗  ╚██╔╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ██║  ██║███████╗╚██████╔╝██║███████║   ██║   ██║  ██║   ██║&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *    ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pragma solidity 0.4.24;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F; IV is value needed to have a vanity address starting with `0x820`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F; IV: 9513&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @dev The interface a contract MUST implement if it is the implementer of&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; some (other) interface for any address other than itself.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;interface ERC820ImplementerInterface {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates whether the contract implements the interface `interfaceHash` for the address `addr` or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param interfaceHash keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param addr Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return ERC820_ACCEPT_MAGIC only if the contract implements `interfaceHash` for the address `addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @title ERC820 Pseudo-introspection Registry Contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @author Jordi Baylina and Jacques Dafflon&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @notice This contract is the official implementation of the ERC820 Registry.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&#x2F;&#x2F; @notice For more details, see https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-820&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;contract ERC820Registry {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice ERC165 Invalid ID.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes4 constant INVALID_ID = 0xffffffff;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256(&amp;#39;supportsInterface(bytes4)&amp;#39;))`).&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes4 constant ERC165ID = 0x01ffc9a7;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Magic value which is returned if a contract implements an interface on behalf of some other address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    bytes32 constant ERC820_ACCEPT_MAGIC = keccak256(abi.encodePacked(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;));&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping (address =&amp;gt; mapping(bytes32 =&amp;gt; address)) interfaces;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping (address =&amp;gt; address) managers;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    mapping (address =&amp;gt; mapping(bytes4 =&amp;gt; bool)) erc165Cached;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates a contract is the `implementer` of `interfaceHash` for `addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Indicates `newManager` is the address of the new manager for `addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    event ManagerChanged(address indexed addr, address indexed newManager);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Query if an address implements an interface and through which contract.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address being queried for the implementer of an interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; E.g., `web3.utils.keccak256(&amp;#39;ERC777Token&amp;#39;)`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return The address of the contract which implements the interface `_interfaceHash` for `_addr`&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; or `0x0` if `_addr` did not register an implementer for this interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        address addr = _addr == 0 ? msg.sender : _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (isERC165Interface(_interfaceHash)) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            bytes4 erc165InterfaceHash = bytes4(_interfaceHash);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return implementsERC165Interface(addr, erc165InterfaceHash) ? addr : 0;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return interfaces[addr][_interfaceHash];&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Sets the contract which implements a specific interface for an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; Only the manager defined for that address can set it.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; (Each address is the manager for itself until it sets a new manager.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address to define the interface for. (If `_addr == 0` then `msg.sender` is assumed.)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash keccak256 hash of the name of the interface as a string.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; For example, `web3.utils.keccak256(&amp;#39;ERC777TokensRecipient&amp;#39;)` for the `ERC777TokensRecipient` interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _implementer Contract address implementing _interfaceHash for _addr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        address addr = _addr == 0 ? msg.sender : _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(getManager(addr) == msg.sender, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not the manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(!isERC165Interface(_interfaceHash), &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Must not be a ERC165 hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (_implementer != 0 &amp;amp;&amp;amp; _implementer != msg.sender) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            require(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                ERC820ImplementerInterface(_implementer)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    .canImplementInterfaceForAddress(_interfaceHash, addr) == ERC820_ACCEPT_MAGIC,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;                \&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Does not implement the interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            );&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        interfaces[addr][_interfaceHash] = _implementer;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        emit InterfaceImplementerSet(addr, _interfaceHash, _implementer);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Sets the `_newManager` as manager for the `_addr` address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; The new manager will be able to call `setInterfaceImplementer` for `_addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address for which to set the new manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _newManager Address of the new manager for `addr`.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function setManager(address _addr, address _newManager) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        require(getManager(_addr) == msg.sender, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Not the manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        managers[_addr] = _newManager == _addr ? 0 : _newManager;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        emit ManagerChanged(_addr, _newManager);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Get the manager of an address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _addr Address for which to return the manager.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return Address of the manager for a given address.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function getManager(address _addr) public view returns(address) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        &#x2F;&#x2F; By default the manager of an address is the same address&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (managers[_addr] == 0) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return _addr;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        } else {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return managers[_addr];&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Compute the keccak256 hash of an interface given its name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceName Name of the interface.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return The keccak256 hash of an interface name.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function interfaceHash(string _interfaceName) external pure returns(bytes32) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return keccak256(abi.encodePacked(_interfaceName));&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;* --- ERC165 Related Functions --- *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;* --- Developed in collaboration with William Entriken. --- *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Updates the cache with whether the contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface for which to update the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function updateERC165Cache(address _contract, bytes4 _interfaceId) external {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        interfaces[_contract][_interfaceId] = implementsERC165InterfaceNoCache(_contract, _interfaceId) ? _contract : 0;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        erc165Cached[_contract][_interfaceId] = true;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether a contract implements an ERC165 interface or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; The result may be cached, if not a direct lookup is performed.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return `true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (!erc165Cached[_contract][_interfaceId]) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return implementsERC165InterfaceNoCache(_contract, _interfaceId);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return interfaces[_contract][_interfaceId] == _contract;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _contract Address of the contract to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceId ERC165 interface to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return `true` if `_contract` implements `_interfaceId`, false otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        uint256 success;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        uint256 result;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, ERC165ID);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 0 || result == 0) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, INVALID_ID);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 0 || result != 0) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        (success, result) = noThrowCall(_contract, _interfaceId);&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        if (success == 1 &amp;amp;&amp;amp; result == 1) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;            return true;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return false;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @param _interfaceHash The hash to check.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @return `true` if the hash is a ERC165 interface (ending with 28 zeroes), `false` otherwise.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        return _interfaceHash &amp;amp; 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    &#x2F;&#x2F;&#x2F; @dev Make a call on a contract without throwing if the function does not exist.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    function noThrowCall(address _contract, bytes4 _interfaceId)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        internal view returns (uint256 success, uint256 result)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        bytes4 erc165ID = ERC165ID;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        assembly {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                let x := mload(0x40)               &#x2F;&#x2F; Find empty storage location using &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;free memory pointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                mstore(x, erc165ID)                &#x2F;&#x2F; Place signature at beginning of empty storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                mstore(add(x, 0x04), _interfaceId) &#x2F;&#x2F; Place first argument directly next to signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                success := staticcall(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    30000,                         &#x2F;&#x2F; 30k gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    _contract,                     &#x2F;&#x2F; To addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    x,                             &#x2F;&#x2F; Inputs are stored at location x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    0x08,                          &#x2F;&#x2F; Inputs are 8 bytes long&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    x,                             &#x2F;&#x2F; Store output over input (saves space)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    0x20                           &#x2F;&#x2F; Outputs are 32 bytes long&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                )&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                result := mload(x)                 &#x2F;&#x2F; Load the result&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-support&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x8eecce3912a15087b3f5845d5a74af7712c93d0a8fcd6f2d40f07ed5032022ab&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&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;&#x2F;details&gt;
&lt;h3 id=&quot;interface-name&quot;&gt;Interface Name&lt;&#x2F;h3&gt;
&lt;p&gt;Any interface name is hashed using &lt;code&gt;keccak256&lt;&#x2F;code&gt; and sent to &lt;code&gt;getInterfaceImplementer()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the interface is part of a standard, it is best practice to explicitly state the interface name and link to this published &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; such that other people don&#x27;t have to come here to look up these rules.&lt;&#x2F;p&gt;
&lt;p&gt;For convenience, the registry provides a function to compute the hash on-chain:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&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;Compute the keccak256 hash of an interface given its name.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;65ba36c1&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceName&lt;&#x2F;code&gt;: Name of the interface.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; The &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of an interface name.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;approved-ercs&quot;&gt;&lt;strong&gt;Approved ERCs&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;If the interface is part of an approved ERC, it MUST be named &lt;code&gt;ERC###XXXXX&lt;&#x2F;code&gt; where &lt;code&gt;###&lt;&#x2F;code&gt; is the number of the ERC and XXXXX should be the name of the interface in CamelCase. The meaning of this interface SHOULD be defined in the specified ERC.&lt;&#x2F;p&gt;
&lt;p&gt;Examples:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC20Token&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777Token&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777TokensSender&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256(&quot;ERC777TokensRecipient&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;erc-165-compatible-interfaces&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Compatible Interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, including the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;#erc165-cache&quot;&gt;ERC165 Cache&lt;&#x2F;a&gt;, has been designed and developed with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fulldecent&quot;&gt;William Entriken&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Any interface where the last 28 bytes are zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;) SHALL be considered an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Lookup&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anyone can explicitly check if a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface using the registry by calling one of the two functions below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165Interface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Checks whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The result is cached. If the cache is out of date, it MUST be updated by calling &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt;. (See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;#erc165-cache&quot;&gt;ERC165 Cache&lt;&#x2F;a&gt; for more details.)&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;f712f3e8&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;_contract&lt;&#x2F;code&gt; implements &lt;code&gt;_interfaceId&lt;&#x2F;code&gt;, false otherwise.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; implementsERC165InterfaceNoCache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Checks whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not without using nor updating the cache.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;b7056765&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface to check.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;_contract&lt;&#x2F;code&gt; implements &lt;code&gt;_interfaceId&lt;&#x2F;code&gt;, false otherwise.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; Cache&lt;&#x2F;strong&gt; &lt;a id=&quot;erc165-cache&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whether a contract implements an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface or not can be cached manually to save gas.&lt;&#x2F;p&gt;
&lt;p&gt;If a contract dynamically changes its interface and relies on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; registry, the cache MUST be updated manually---there is no automatic cache invalidation or cache update. Ideally the contract SHOULD automatically update the cache when changing its interface. However anyone MAY update the cache on the contract&#x27;s behalf.&lt;&#x2F;p&gt;
&lt;p&gt;The cache update MUST be done using the &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; updateERC165Cache&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;a41e7d51&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_contract&lt;&#x2F;code&gt;: Address of the contract for which to update the cache.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceId&lt;&#x2F;code&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface for which to update the cache.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;private-user-defined-interfaces&quot;&gt;&lt;strong&gt;Private User-defined Interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;This scheme is extensible. You MAY make up your own interface name and raise awareness to get other people to implement it and then check for those implementations. Have fun but please, you MUST not conflict with the reserved designations above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;set-an-interface-for-an-address&quot;&gt;Set An Interface For An Address&lt;&#x2F;h3&gt;
&lt;p&gt;For any address to set a contract as the interface implementation, it must call the following function of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; registry:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _implementer&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sets the contract which implements a specific interface for an address.&lt;&#x2F;p&gt;
&lt;p&gt;Only the &lt;code&gt;manager&lt;&#x2F;code&gt; defined for that address can set it. (Each address is the manager for itself, see the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;#manager&quot;&gt;manager&lt;&#x2F;a&gt; section for more details.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If  &lt;code&gt;_addr&lt;&#x2F;code&gt; and &lt;code&gt;_implementer&lt;&#x2F;code&gt; are two different addresses, then:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;_implementer&lt;&#x2F;code&gt; MUST implement the &lt;code&gt;ERC820ImplementerInterface&lt;&#x2F;code&gt; (detailed below).&lt;&#x2F;li&gt;
&lt;li&gt;Calling &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; on &lt;code&gt;_implementer&lt;&#x2F;code&gt; with the given &lt;code&gt;_addr&lt;&#x2F;code&gt; and  &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; MUST return the &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt; value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; MUST NOT be an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface---it MUST NOT end with 28 zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_addr&lt;&#x2F;code&gt; MAY be &lt;code&gt;0&lt;&#x2F;code&gt;, then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed. This default value simplifies interactions via multisigs where the data of the transaction to sign is constant regardless of the address of the multisig instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;29965a1d&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address to define the interface for (if &lt;code&gt;_addr == 0&lt;&#x2F;code&gt; them &lt;code&gt;msg.sender&lt;&#x2F;code&gt;: is assumed)&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;: &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of the name of the interface as a string, for example &lt;code&gt;web3.utils.keccak256(&#x27;ERC777TokensRecipient&#x27;)&lt;&#x2F;code&gt; for the ERC777TokensRecipient interface.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_implementer&lt;&#x2F;code&gt;: Contract implementing &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;get-an-implementation-of-an-interface-for-an-address&quot;&gt;Get An Implementation Of An Interface For An Address&lt;&#x2F;h3&gt;
&lt;p&gt;Anyone MAY query the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; Registry to obtain the address of a contract implementing an interface on behalf of some address using the &lt;code&gt;getInterfaceImplementer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&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;Query if an address implements an interface and through which contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If the last 28 bytes of the &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; are zeroes (&lt;code&gt;0&lt;&#x2F;code&gt;), then the first 4 bytes are considered an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface and the registry SHALL forward the call to the contract at &lt;code&gt;_addr&lt;&#x2F;code&gt; to see if it implements the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface (the first 4 bytes of &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;). The registry SHALL also cache &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; queries to reduce gas consumption. Anyone MAY call the &lt;code&gt;erc165UpdateCache&lt;&#x2F;code&gt; function to update whether a contract implements an interface or not.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;_addr&lt;&#x2F;code&gt; MAY be &lt;code&gt;0&lt;&#x2F;code&gt;, then &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed. This default value is consistent with the behavior of the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function and simplifies interactions via multisigs where the data of the transaction to sign is constant regardless of the address of the multisig instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;aabbb8ca&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address being queried for the implementer of an interface. (If &lt;code&gt;_addr == 0&lt;&#x2F;code&gt; them &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is assumed.)&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_interfaceHash&lt;&#x2F;code&gt;: keccak256 hash of the name of the interface as a string. E.g. &lt;code&gt;web3.utils.keccak256(&#x27;ERC777Token&#x27;)&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; The address of the contract which implements the interface &lt;code&gt;_interfaceHash&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt; or &lt;code&gt;0x0&lt;&#x2F;code&gt; if &lt;code&gt;_addr&lt;&#x2F;code&gt; did not register an implementer for this interface.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;interface-implementation-erc820implementerinterface&quot;&gt;Interface Implementation (&lt;code&gt;ERC820ImplementerInterface&lt;&#x2F;code&gt;)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC820ImplementerInterface&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @notice&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Indicates whether the contract implements the interface `interfaceHash` for the address `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Address for which the contract will implement the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; keccak256 hash of the name of the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ERC820_ACCEPT_MAGIC&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; only if the contract implements `ìnterfaceHash` for the address `addr`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any contract being registered as the implementation of an interface for a given address MUST implement said interface. In addition if it implements an interface on behalf of a different address, the contract MUST implement the &lt;code&gt;ERC820ImplementerInterface&lt;&#x2F;code&gt; shown above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; canImplementInterfaceForAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceHash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;)&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;Indicates whether a contract implements an interface (&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;) for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;If a contract implements the interface (&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;) for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;), it MUST return &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt; when called with the &lt;code&gt;addr&lt;&#x2F;code&gt; and the &lt;code&gt;interfaceHash&lt;&#x2F;code&gt;. If it does not implement the &lt;code&gt;interfaceHash&lt;&#x2F;code&gt; for a given address (&lt;code&gt;addr&lt;&#x2F;code&gt;), it MUST NOT return &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;f0083250&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;interfaceHash&lt;&#x2F;code&gt;: Hash of the interface which is implemented&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;addr&lt;&#x2F;code&gt;: Address for which the interface is implemented&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt; only if the contract implements &lt;code&gt;ìnterfaceHash&lt;&#x2F;code&gt; for the address &lt;code&gt;addr&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The special value &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt; is defined as the &lt;code&gt;keccka256&lt;&#x2F;code&gt; hash of the string &lt;code&gt;&quot;ERC820_ACCEPT_MAGIC&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; ERC820_ACCEPT_MAGIC &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ERC820_ACCEPT_MAGIC&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&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&gt;
&lt;p&gt;The reason to return &lt;code&gt;ERC820_ACCEPT_MAGIC&lt;&#x2F;code&gt; instead of a boolean is to prevent cases where a contract fails to implement the &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; but implements a fallback function which does not throw. In this case, since &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; does not exist, the fallback function is called instead, executed without throwing and returns &lt;code&gt;1&lt;&#x2F;code&gt;. Thus making it appear as if &lt;code&gt;canImplementInterfaceForAddress&lt;&#x2F;code&gt; returned &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;manager&quot;&gt;Manager&lt;&#x2F;h3&gt;
&lt;p&gt;The manager of an address (regular account or a contract) is the only entity allowed to register implementations of interfaces for the address. By default, any address is its own manager.&lt;&#x2F;p&gt;
&lt;p&gt;The manager can transfer its role to another address by calling &lt;code&gt;setManager&lt;&#x2F;code&gt; on the registry contract with the address for which to transfer the manager and the address of the new manager.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;setManager&lt;&#x2F;code&gt; Function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _newManager&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sets the &lt;code&gt;_newManager&lt;&#x2F;code&gt; as manager for the &lt;code&gt;_addr&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;The new manager will be able to call &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; for &lt;code&gt;_addr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;_newManager&lt;&#x2F;code&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;, the manager is reset to &lt;code&gt;_addr&lt;&#x2F;code&gt; itself as the manager.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;5df8122f&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address for which to set the new manager.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_newManager&lt;&#x2F;code&gt;: The address of the new manager for &lt;code&gt;_addr&lt;&#x2F;code&gt;. (Pass &lt;code&gt;0x0&lt;&#x2F;code&gt; to reset the manager to &lt;code&gt;_addr&lt;&#x2F;code&gt;.)&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;getManager&lt;&#x2F;code&gt; Function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; getManager&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&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;Get the manager of an address.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;3d584063&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;_addr&lt;&#x2F;code&gt;: Address for which to return the manager.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Address of the manager for a given address.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standards offers a way for any type of address (externally owned and contracts) to implement an interface and potentially delegate the implementation of the interface to a proxy contract. This delegation to a proxy contract is necessary for externally owned accounts and useful to avoid redeploying existing contracts such as multisigs and DAOs.&lt;&#x2F;p&gt;
&lt;p&gt;The registry can also act as a &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; cache in order to save gas when looking up if a contract implements a specific &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; interface. This cache is intentionally kept simple, without automatic cache update or invalidation. Anyone can easily and safely update the cache for any interface and any contract by calling the &lt;code&gt;updateERC165Cache&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;The registry is deployed using a keyless deployment method relying on a single-use deployment address to ensure no one controls the registry, thereby ensuring trust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backward-compatibility&quot;&gt;Backward Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This standard is backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt;, as both methods MAY be implemented without conflicting with each other.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Please check the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbaylina&#x2F;ERC820&quot;&gt;jbaylina&#x2F;ERC820&lt;&#x2F;a&gt; repository for the full test suite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation is available in the repo: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbaylina&#x2F;ERC820&quot;&gt;jbaylina&#x2F;ERC820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: DAO Fork&quot;</title>
        <published>2017-11-26T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Casey Detrio</name><uri>https://github.com/cdetrio</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/779/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/779/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:779"
            label="EIP-779" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/779/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This documents the changes included in the hard fork named &quot;DAO Fork&quot;. Unlike other hard forks, the DAO Fork did not change the protocol; all EVM opcodes, transaction format, block structure, and so on remained the same. Rather, the DAO Fork was an &quot;irregular state change&quot; that transferred ether balances from a list of accounts (&quot;child DAO&quot; contracts) into a specified account (the &quot;WithdrawDAO&quot; contract).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: DAO Fork&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block == 1,920,000 on Mainnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;See references [1] and [2] for the original, full specification. It is summarized here for convenience.&lt;&#x2F;p&gt;
&lt;p&gt;At block 1880000, the following accounts are encoded into a list &lt;code&gt;L&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The DAO (&lt;code&gt;0xbb9bc244d798123fde783fcc1c72d3bb8c189413&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;its extraBalance (&lt;code&gt;0x807640a13483f8ac783c557fcdf27be11ea4ac7a&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;all children of the DAO creator (&lt;code&gt;0x4a574510c7014e4ae985403536074abe582adfc8&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;and the extraBalance of each child&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;details&gt;
&lt;summary&gt;Reference list L&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd4fe7bc31cedb7bfb8a345f31e668033056b2728,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xecd135fa4f61a655311e86238c92adcd779555d2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x1975bd06d486162d5dc297798dfc41edd5d160a7,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x319f70bab6845585f412ec7724b744fec6095c85,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5c8536898fbb74fc7445814902fd08422eac56d0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6966ab0d485353095148a2155858910e0965b6f9,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x779543a0491a837ca36ce8c635d6154e3c4911a6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x2a5ed960395e2a49b1c758cef4aa15213cfd874c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9c50426be05db97f5d64fc54bf89eff947f0a321,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x200450f06520bdd6c527622a273333384d870efb,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xbe8539bfe837b67d1282b2b1d61c3f723966f049,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf1385fb24aad0cd7432824085e42aff90886fef5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x51e0ddd9998364a2eb38588679f0d2c42653e4a6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x627a0a960c079c21c34f7612d5d230e01b4ad4c7,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf0b1aa0eb660754448a7937c022e30aa692fe0c5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x24c4d950dfd4dd1902bbed3508144a54542bba94,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9f27daea7aca0aa0446220b98d028715e3bc803d,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x63ed5a272de2f6d968408b4acb9024f4cc208ebf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6f6704e5a10332af6672e50b3d9754dc460dfa4d,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x492ea3bb0f3315521c31f273e565b868fc090f17,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9ea779f907f0b315b364b0cfc39a0fde5b02a416,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xceaeb481747ca6c540a000c1f3641f8cef161fa7,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xcc34673c6c40e791051898567a1222daf90be287,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x579a80d909f346fbfb1189493f521d7f48d52238,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xe308bd1ac5fda103967359b2712dd89deffb7973,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xac1ecab32727358dba8962a0f3b261731aad9723,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4fd6ace747f06ece9c49699c7cabc62d02211f75,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x440c59b325d2997a134c2c7c60a8c61611212bad,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4486a3d68fac6967006d7a517b889fd3f98c102b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9c15b54878ba618f494b38f0ae7443db6af648ba,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x27b137a85656544b1ccb5a0f2e561a5703c6a68f,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x23b75c2f6791eef49c69684db4c6c1f93bf49a50,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xb9637156d330c0d605a791f1c31ba5890582fe1c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6131c42fa982e56929107413a9d526fd99405560,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x1591fc0f688c81fbeb17f5426a162a7024d430c2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x542a9515200d14b68e934e9830d91645a980dd7a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xc4bbd073882dd2add2424cf47d35213405b01324,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x3ba4d81db016dc2890c81f3acec2454bff5aada5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xe4ae1efdfc53b73893af49113d8694a057b9c0d1,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x0737a6b837f97f46ebade41b9bc3e1c509c85c53,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x97f43a37f595ab5dd318fb46e7a155eae057317a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x52c5317c848ba20c7504cb2c8052abd1fde29d03,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4863226780fe7c0356454236d3b1c8792785748d,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5d2b2e6fcbe3b11d26b525e085ff818dae332479,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x057b56736d32b86616a10f619859c6cd6f59092a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9aa008f65de0b923a2a4f02012ad034a5e2e2192,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x304a554a310c7e546dfe434669c62820b7d83490,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4deb0033bb26bc534b197e61d19e0733e5679784,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4fa802324e929786dbda3b8820dc7834e9134a2a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9da397b9e80755301a3b32173283a91c0ef6c87e,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5dc28b15dffed94048d73806ce4b7a4612a1d48f,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x12e626b0eebfe86a56d633b9864e389b45dcb260,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd164b088bd9108b60d0ca3751da4bceb207b0782,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6231b6d0d5e77fe001c2a460bd9584fee60d409b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x1cba23d343a983e9b5cfd19496b9a9701ada385f,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xa82f360a8d3455c5c41366975bde739c37bfeb8a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x005f5cee7a43331d5a3d3eec71305925a62f34b6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd131637d5275fd1a68a3200f4ad25c71a2a9522e,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xbc07118b9ac290e4622f5e77a0853539789effbe,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x47e7aa56d6bdf3f36be34619660de61275420af8,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xacd87e28b0c9d1254e868b81cba4cc20d9a32225,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xadf80daec7ba8dcf15392f1ac611fff65d94f880,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5524c55fb03cf21f549444ccbecb664d0acad706,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x40b803a9abce16f50f36a77ba41180eb90023925,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xfe24cdd8648121a43a7c86d289be4dd2951ed49f,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x17802f43a0137c506ba92291391a8a8f207f487d,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x253488078a4edf4d6f42f113d1e62836a942cf1a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xb136707642a4ea12fb4bae820f03d2562ebff487,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf14c14075d6c4ed84b86798af0956deef67365b5,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xca544e5c4687d109611d0f8f928b53a25af72448,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x6d87578288b6cb5549d5076a207456a1f6a63dc0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x2b3455ec7fedf16e646268bf88846bd7a2319bb2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xd343b217de44030afaa275f54d31a9317c7f441e,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x84ef4b2357079cd7a7c69fd7a37cd0609a679106,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xda2fef9e4a3230988ff17df2165440f37e8b1708,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf4c64518ea10f995918a454158c6b61407ea345c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xbb9bc244d798123fde783fcc1c72d3bb8c189413,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x807640a13483f8ac783c557fcdf27be11ea4ac7a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;At the beginning of block 1920000, all ether throughout all accounts in &lt;code&gt;L&lt;&#x2F;code&gt; will be transferred to a contract deployed at &lt;code&gt;0xbf4ed7b27f1d666546e30d74d50d173d20bca754&lt;&#x2F;code&gt;. The contract was created from the following Solidity code (compiler version &lt;code&gt;v0.3.5-2016-07-01-48238c9&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deployed on mainnet at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754&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 class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DAO&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalSupply&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; WithdrawDAO&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DAO &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; mainDAO &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DAO&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0xbb9bc244d798123fde783fcc1c72d3bb8c189413&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; trustee &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xda4a4626d3e16e094de3225a751aab7128e96526&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        uint&lt;&#x2F;span&gt;&lt;span&gt; balance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; mainDAO&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;mainDAO&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;balance&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;            throw&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; trusteeWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        trustee&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;balance &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; mainDAO&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; mainDAO&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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&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;This contract is deployed on Mainnet in block 1883496 in transaction hash &lt;code&gt;0xfeae1ff3cf9b6927d607744e3883ea105fb16042d4639857d9cfce3eba644286&lt;&#x2F;code&gt;. The deployment code of the contract is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x606060405273da4a4626d3e16e094de3225a751aab7128e96526600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550610462806100516000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e6e504a1461005a5780633ccfd60b14610069578063eedcf50a14610078578063fdf97cb2146100b157610058565b005b61006760048050506100ea565b005b6100766004805050610277565b005b6100856004805050610424565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100be600480505061043c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166318160ddd604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823130604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f11561000257505050604051805190602001503073ffffffffffffffffffffffffffffffffffffffff16310103604051809050600060405180830381858888f19350505050505b565b600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823133604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150905073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166323b872dd333084604051847c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150158061041657503373ffffffffffffffffffffffffffffffffffffffff16600082604051809050600060405180830381858888f19350505050155b1561042057610002565b5b50565b73bb9bc244d798123fde783fcc1c72d3bb8c18941381565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This deployment results in the runtime bytecode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e6e504a1461005a5780633ccfd60b14610069578063eedcf50a14610078578063fdf97cb2146100b157610058565b005b61006760048050506100ea565b005b6100766004805050610277565b005b6100856004805050610424565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100be600480505061043c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166318160ddd604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823130604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f11561000257505050604051805190602001503073ffffffffffffffffffffffffffffffffffffffff16310103604051809050600060405180830381858888f19350505050505b565b600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823133604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150905073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166323b872dd333084604051847c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150158061041657503373ffffffffffffffffffffffffffffffffffffffff16600082604051809050600060405180830381858888f19350505050155b1561042057610002565b5b50565b73bb9bc244d798123fde783fcc1c72d3bb8c18941381565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Blocks with block numbers in the range [1_920_000, 1_920_009] &lt;strong&gt;MUST&lt;&#x2F;strong&gt; have &lt;code&gt;0x64616f2d686172642d666f726b&lt;&#x2F;code&gt; (hex encoded ASCII string &lt;code&gt;dao-hard-fork&lt;&#x2F;code&gt;) in the &lt;code&gt;extraData&lt;&#x2F;code&gt; field of the block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.slock.it&#x2F;hard-fork-specification-24b889e70703&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;07&#x2F;15&#x2F;to-fork-or-not-to-fork&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum Node Records (ENR)</title>
        <published>2017-11-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Felix Lange</name><email>fjl@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/778/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/devp2p/issues/43" />
        

        <id>https://wg-eips.ritovision.com/778/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:778"
            label="EIP-778" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/778/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This EIP defines Ethereum Node Records, an open format for p2p connectivity information.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;Ethereum nodes discover each other through the node discovery protocol. The purpose of
that protocol is relaying node identity public keys (on the secp256k1 curve), their IP
address and two port numbers. No other information can be relayed.&lt;&#x2F;p&gt;
&lt;p&gt;This specification seeks to lift the restrictions of the discovery v4 protocol by defining
a flexible format, the &lt;em&gt;node record&lt;&#x2F;em&gt;, for connectivity-related information. Node records
can be relayed through a future version of the node discovery protocol. They can also be
relayed through arbitrary other mechanisms such as DNS, ENS, a devp2p subprotocol, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Node records improve cryptographic agility and handling of protocol upgrades. A record can
contain information about arbitrary transport protocols and public key material associated
with them.&lt;&#x2F;p&gt;
&lt;p&gt;Another goal of the new format is to provide authoritative updates of connectivity
information. If a node changes its endpoint and publishes a new record, other nodes should
be able to determine which record is newer.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;The components of a node record are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;signature&lt;&#x2F;code&gt;: cryptographic signature of record contents&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;seq&lt;&#x2F;code&gt;: The sequence number, a 64-bit unsigned integer. Nodes should increase the number
whenever the record changes and republish the record.&lt;&#x2F;li&gt;
&lt;li&gt;The remainder of the record consists of arbitrary key&#x2F;value pairs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A record&#x27;s signature is made and validated according to an &lt;em&gt;identity scheme&lt;&#x2F;em&gt;. The identity
scheme is also responsible for deriving a node&#x27;s address in the DHT.&lt;&#x2F;p&gt;
&lt;p&gt;The key&#x2F;value pairs must be sorted by key and must be unique, i.e. any key may be present
only once. The keys can technically be any byte sequence, but ASCII text is preferred. Key
names in the table below have pre-defined meaning.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Key&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;id&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;name of identity scheme, e.g. &quot;v4&quot;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;secp256k1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;compressed secp256k1 public key, 33 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;ip&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;IPv4 address, 4 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;tcp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;TCP port, big endian integer&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;udp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;UDP port, big endian integer&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;ip6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;IPv6 address, 16 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;tcp6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;IPv6-specific TCP port, big endian integer&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;udp6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;IPv6-specific UDP port, big endian integer&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;All keys except &lt;code&gt;id&lt;&#x2F;code&gt; are optional, including IP addresses and ports. A record without
endpoint information is still valid as long as its signature is valid. If no &lt;code&gt;tcp6&lt;&#x2F;code&gt; &#x2F;
&lt;code&gt;udp6&lt;&#x2F;code&gt; port is provided, the &lt;code&gt;tcp&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;udp&lt;&#x2F;code&gt; port applies to both IP addresses. Declaring
the same port number in both &lt;code&gt;tcp&lt;&#x2F;code&gt;, &lt;code&gt;tcp6&lt;&#x2F;code&gt; or &lt;code&gt;udp&lt;&#x2F;code&gt;, &lt;code&gt;udp6&lt;&#x2F;code&gt; should be avoided but doesn&#x27;t
render the record invalid.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rlp-encoding&quot;&gt;RLP Encoding&lt;&#x2F;h3&gt;
&lt;p&gt;The canonical encoding of a node record is an RLP list of &lt;code&gt;[signature, seq, k, v, ...]&lt;&#x2F;code&gt;.
The maximum encoded size of a node record is 300 bytes. Implementations should reject
records larger than this size.&lt;&#x2F;p&gt;
&lt;p&gt;Records are signed and encoded as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;content   = [seq, k, v, ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;signature = sign(content)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;record    = [signature, seq, k, v, ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;text-encoding&quot;&gt;Text Encoding&lt;&#x2F;h3&gt;
&lt;p&gt;The textual form of a node record is the base64 encoding of its RLP representation,
prefixed by &lt;code&gt;enr:&lt;&#x2F;code&gt;. Implementations should use the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc4648#section-5&quot;&gt;URL-safe base64 alphabet&lt;&#x2F;a&gt;
and omit padding characters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;v4-identity-scheme&quot;&gt;&quot;v4&quot; Identity Scheme&lt;&#x2F;h3&gt;
&lt;p&gt;This specification defines a single identity scheme to be used as the default until other
schemes are defined by further EIPs. The &quot;v4&quot; scheme is backwards-compatible with the
cryptosystem used by Node Discovery v4.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To sign record &lt;code&gt;content&lt;&#x2F;code&gt; with this scheme, apply the keccak256 hash function (as used by
the EVM) to &lt;code&gt;content&lt;&#x2F;code&gt;, then create a signature of the hash. The resulting 64-byte
signature is encoded as the concatenation of the &lt;code&gt;r&lt;&#x2F;code&gt; and &lt;code&gt;s&lt;&#x2F;code&gt; signature values (the
recovery ID &lt;code&gt;v&lt;&#x2F;code&gt; is omitted).&lt;&#x2F;li&gt;
&lt;li&gt;To verify a record, check that the signature was made by the public key in the
&quot;secp256k1&quot; key&#x2F;value pair of the record.&lt;&#x2F;li&gt;
&lt;li&gt;To derive a node address, take the keccak256 hash of the uncompressed public key.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h1&gt;
&lt;p&gt;The format is meant to suit future needs in two ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Adding new key&#x2F;value pairs: This is always possible and doesn&#x27;t require implementation
consensus. Existing clients will accept any key&#x2F;value pairs regardless of whether they
can interpret their content.&lt;&#x2F;li&gt;
&lt;li&gt;Adding identity schemes: these need implementation consensus because the network won&#x27;t
accept the signature otherwise. To introduce a new identity scheme, propose an EIP and
get it implemented. The scheme can be used as soon as most clients accept it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The size of a record is limited because records are relayed frequently and may be included
in size-constrained protocols such as DNS. A record containing a IPv4 address, when signed
using the &quot;v4&quot; scheme occupies roughly 120 bytes, leaving plenty of room for additional
metadata.&lt;&#x2F;p&gt;
&lt;p&gt;You might wonder about the need for so many pre-defined keys related to IP addresses and
ports. This need arises because residential and mobile network setups often put IPv4
behind NAT while IPv6 traffic—if supported—is directly routed to the same host. Declaring
both address types ensures a node is reachable from IPv4-only locations and those
supporting both protocols.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;test-vectors&quot;&gt;Test Vectors&lt;&#x2F;h1&gt;
&lt;p&gt;This is an example record containing the IPv4 address &lt;code&gt;127.0.0.1&lt;&#x2F;code&gt; and UDP port &lt;code&gt;30303&lt;&#x2F;code&gt;.
The node ID is &lt;code&gt;a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The record is signed using the &quot;v4&quot; identity scheme using sequence number &lt;code&gt;1&lt;&#x2F;code&gt; and this
private key:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The RLP structure of the record is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&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&gt;  7098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  01,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;id&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;v4&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;ip&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  7f000001,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;secp256k1&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;udp&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  765f,&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;h1 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h1&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Token Standard</title>
        <published>2017-11-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Jacques Dafflon</name><email>mail@0xjac.com</email>
	</author>
	
	<author>
		<name>Jordi Baylina</name><email>jordi@baylina.cat</email>
	</author>
	
	<author>
		<name>Thomas Shababi</name><email>tom@truelevel.io</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/777/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/777" />
        

        <id>https://wg-eips.ritovision.com/777/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:777"
            label="ERC-777" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/777/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines standard interfaces and behaviors for token contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This standard defines a new way to interact with a token contract while remaining backward compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It defines advanced features to interact with tokens.
Namely, &lt;em&gt;operators&lt;&#x2F;em&gt; to send tokens on behalf of another address—contract or regular account—and
send&#x2F;receive &lt;em&gt;hooks&lt;&#x2F;em&gt; to offer token holders more control over their tokens.&lt;&#x2F;p&gt;
&lt;p&gt;It takes advantage of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; to find out whether and where to notify contracts and regular addresses
when they receive tokens as well as to allow compatibility with already-deployed contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This standard tries to improve upon the widely used &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token standard.
The main advantages of this standard are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Uses the same philosophy as Ether in that tokens are sent with &lt;code&gt;send(dest, value, data)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Both contracts and regular addresses can control and reject which token they send
by registering a &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook.
(Rejection is done by &lt;code&gt;revert&lt;&#x2F;code&gt;ing in the hook function.)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Both contracts and regular addresses can control and reject which token they receive
by registering a &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook.
(Rejection is done by &lt;code&gt;revert&lt;&#x2F;code&gt;ing in the hook function.)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook allows to send tokens to a contract and notify it in a single transaction,
unlike &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; which requires a double call (&lt;code&gt;approve&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;transferFrom&lt;&#x2F;code&gt;) to achieve this.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The holder can &quot;authorize&quot; and &quot;revoke&quot; operators which can send tokens on their behalf.
These operators are intended to be verified contracts
such as an exchange, a cheque processor or an automatic charging system.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Every token transaction contains &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; bytes fields
to be used freely to pass data from the holder and the operator, respectively.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It is backward compatible with wallets that do not contain the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook function
by deploying a proxy contract implementing the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook for the wallet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;erc777token-token-contract&quot;&gt;ERC777Token (Token Contract)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC777Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; granularity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; defaultOperators&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isOperatorFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; operatorSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; operatorBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Sent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Minted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Burned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AuthorizedOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RevokedOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The token contract MUST implement the above interface.
The implementation MUST follow the specifications described below.&lt;&#x2F;p&gt;
&lt;p&gt;The token contract MUST register the &lt;code&gt;ERC777Token&lt;&#x2F;code&gt; interface with its own address via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is done by calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; registry
with the token contract address as both the address and the implementer
and the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC777Token&lt;&#x2F;code&gt; (&lt;code&gt;0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054&lt;&#x2F;code&gt;)
as the interface hash.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;If the contract has a switch to enable or disable ERC-777 functions, every time the switch is triggered,
the token MUST register or unregister the &lt;code&gt;ERC777Token&lt;&#x2F;code&gt; interface for its own address accordingly via ERC1820.
Unregistering implies calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; with the token contract address as the address,
the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC777Token&lt;&#x2F;code&gt; as the interface hash and &lt;code&gt;0x0&lt;&#x2F;code&gt; as the implementer.
(See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;#set-an-interface-for-an-address&quot;&gt;Set An Interface For An Address&lt;&#x2F;a&gt; in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; for more details.)&lt;&#x2F;p&gt;
&lt;p&gt;When interacting with the token contract, all amounts and balances MUST be unsigned integers.
I.e. internally, all values are stored as a denomination of 1E-18 of a token.
The display denomination—to display any amount to the end user—MUST
be 10&lt;sup&gt;18&lt;&#x2F;sup&gt; of the internal denomination.&lt;&#x2F;p&gt;
&lt;p&gt;In other words, the internal denomination is similar to a wei
and the display denomination is similar to an ether.
It is equivalent to an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;decimals&lt;&#x2F;code&gt; function returning &lt;code&gt;18&lt;&#x2F;code&gt;.
E.g. if a token contract returns a balance of &lt;code&gt;500,000,000,000,000,000&lt;&#x2F;code&gt; (0.5×10&lt;sup&gt;18&lt;&#x2F;sup&gt;) for a user,
the user interface MUST show &lt;code&gt;0.5&lt;&#x2F;code&gt; tokens to the user.
If the user wishes to send &lt;code&gt;0.3&lt;&#x2F;code&gt; tokens,
the contract MUST be called with an amount of &lt;code&gt;300,000,000,000,000,000&lt;&#x2F;code&gt; (0.3×10&lt;sup&gt;18&lt;&#x2F;sup&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;User Interfaces which are generated programmatically from the ABI of the token contract
MAY use and display the internal denomination.
But this MUST be made clear, for example by displaying the &lt;code&gt;uint256&lt;&#x2F;code&gt; type.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;view-functions&quot;&gt;&lt;strong&gt;View Functions&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;view&lt;&#x2F;code&gt; functions detailed below MUST be implemented.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;name&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;Get the name of the token, e.g., &lt;code&gt;&quot;MyToken&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;06fdde03&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Name of the token.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;symbol&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;Get the symbol of the token, e.g., &lt;code&gt;&quot;MYT&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;95d89b41&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Symbol of the token.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;totalSupply&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Get the total number of minted tokens.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The total supply MUST be equal to the sum of the balances of all addresses—as
returned by the &lt;code&gt;balanceOf&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The total supply MUST be equal to the sum of all the minted tokens
as defined in all the &lt;code&gt;Minted&lt;&#x2F;code&gt; events minus the sum of all the burned tokens as defined in all the &lt;code&gt;Burned&lt;&#x2F;code&gt; events.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;18160ddd&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Total supply of tokens currently in circulation.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Get the balance of the account with address &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The balance MUST be zero (&lt;code&gt;0&lt;&#x2F;code&gt;) or higher.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;70a08231&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;holder&lt;&#x2F;code&gt;: Address for which the balance is returned.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; Amount of tokens held by &lt;code&gt;holder&lt;&#x2F;code&gt; in the token contract.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;granularity&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; granularity&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Get the smallest part of the token that&#x27;s not divisible.&lt;&#x2F;p&gt;
&lt;p&gt;In other words, the granularity is the smallest amount of tokens (in the internal denomination)
which MAY be minted, sent or burned at any time.&lt;&#x2F;p&gt;
&lt;p&gt;The following rules MUST be applied regarding the &lt;em&gt;granularity&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;granularity&lt;&#x2F;em&gt; value MUST be set at creation time.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;granularity&lt;&#x2F;em&gt; value MUST NOT be changed, ever.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;granularity&lt;&#x2F;em&gt; value MUST be greater than or equal to &lt;code&gt;1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;All balances MUST be a multiple of the granularity.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any amount of tokens (in the internal denomination) minted, sent or burned
MUST be a multiple of the &lt;em&gt;granularity&lt;&#x2F;em&gt; value.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any operation that would result in a balance that&#x27;s not a multiple of the &lt;em&gt;granularity&lt;&#x2F;em&gt; value
MUST be considered invalid, and the transaction MUST &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Most tokens SHOULD be fully partition-able.
I.e., this function SHOULD return &lt;code&gt;1&lt;&#x2F;code&gt; unless there is a good reason for not allowing any fraction of the token.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;556f0dc7&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; The smallest non-divisible part of the token.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#defaultOperators&quot;&gt;&lt;code&gt;defaultOperators&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#isOperatorFor&quot;&gt;&lt;code&gt;isOperatorFor&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; are also &lt;code&gt;view&lt;&#x2F;code&gt; functions,
defined under the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#operators&quot;&gt;operators&lt;&#x2F;a&gt; for consistency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatibility requirement&lt;&#x2F;em&gt;:&lt;br &#x2F;&gt;
The decimals of the token MUST always be &lt;code&gt;18&lt;&#x2F;code&gt;.
For a &lt;em&gt;pure&lt;&#x2F;em&gt; ERC-777 token the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;decimals&lt;&#x2F;code&gt; function is OPTIONAL,
and its existence SHALL NOT be relied upon when interacting with the token contract.
(The decimal value of &lt;code&gt;18&lt;&#x2F;code&gt; is implied.)
For an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatible token, the &lt;code&gt;decimals&lt;&#x2F;code&gt; function is REQUIRED and MUST return &lt;code&gt;18&lt;&#x2F;code&gt;.
(In &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;, the &lt;code&gt;decimals&lt;&#x2F;code&gt; function is OPTIONAL.
If the function is not present, the &lt;code&gt;decimals&lt;&#x2F;code&gt; value is not clearly defined and may be assumed to be &lt;code&gt;0&lt;&#x2F;code&gt;.
Hence for compatibility reasons, &lt;code&gt;decimals&lt;&#x2F;code&gt; MUST be implemented for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatible tokens.)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;operators&quot;&gt;&lt;strong&gt;Operators&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;An &lt;code&gt;operator&lt;&#x2F;code&gt; is an address which is allowed to send and burn tokens on behalf of some &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When an address becomes an &lt;em&gt;operator&lt;&#x2F;em&gt; for a &lt;em&gt;holder&lt;&#x2F;em&gt;, an &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; event MUST be emitted.
The &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;operator&lt;&#x2F;code&gt; (topic 1) and &lt;code&gt;holder&lt;&#x2F;code&gt; (topic 2)
MUST be the addresses of the &lt;em&gt;operator&lt;&#x2F;em&gt; and the &lt;em&gt;holder&lt;&#x2F;em&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;When a &lt;em&gt;holder&lt;&#x2F;em&gt; revokes an &lt;em&gt;operator&lt;&#x2F;em&gt;, a &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; event MUST be emitted.
The &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;operator&lt;&#x2F;code&gt; (topic 1) and &lt;code&gt;holder&lt;&#x2F;code&gt; (topic 2)
MUST be the addresses of the &lt;em&gt;operator&lt;&#x2F;em&gt; and the &lt;em&gt;holder&lt;&#x2F;em&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: A &lt;em&gt;holder&lt;&#x2F;em&gt; MAY have multiple &lt;em&gt;operators&lt;&#x2F;em&gt; at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;The token MAY define &lt;em&gt;default operators&lt;&#x2F;em&gt;.
A &lt;em&gt;default operator&lt;&#x2F;em&gt; is an implicitly authorized &lt;em&gt;operator&lt;&#x2F;em&gt; for all &lt;em&gt;holders&lt;&#x2F;em&gt;.
&lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; events MUST NOT be emitted when defining the &lt;em&gt;default operators&lt;&#x2F;em&gt;.
The rules below apply to &lt;em&gt;default operators&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST define &lt;em&gt;default operators&lt;&#x2F;em&gt; at creation time.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;default operators&lt;&#x2F;em&gt; MUST be invariants. I.e., the token contract MUST NOT add or remove &lt;em&gt;default operators&lt;&#x2F;em&gt; ever.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; events MUST NOT be emitted when defining &lt;em&gt;default operators&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;holder&lt;&#x2F;em&gt; MUST be allowed to revoke a &lt;em&gt;default operator&lt;&#x2F;em&gt;
(unless the &lt;em&gt;holder&lt;&#x2F;em&gt; is the &lt;em&gt;default operator&lt;&#x2F;em&gt; in question).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;em&gt;holder&lt;&#x2F;em&gt; MUST be allowed to re-authorize a previously revoked &lt;em&gt;default operator&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When a &lt;em&gt;default operator&lt;&#x2F;em&gt; is explicitly authorized or revoked for a specific &lt;em&gt;holder&lt;&#x2F;em&gt;,
an &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; or &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; event (respectively) MUST be emitted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following rules apply to any &lt;em&gt;operator&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An address MUST always be an &lt;em&gt;operator&lt;&#x2F;em&gt; for itself. Hence an address MUST NOT ever be revoked as its own &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If an address is an &lt;em&gt;operator&lt;&#x2F;em&gt; for a &lt;em&gt;holder&lt;&#x2F;em&gt;, &lt;code&gt;isOperatorFor&lt;&#x2F;code&gt; MUST return &lt;code&gt;true&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If an address is not an &lt;em&gt;operator&lt;&#x2F;em&gt; for a &lt;em&gt;holder&lt;&#x2F;em&gt;, &lt;code&gt;isOperatorFor&lt;&#x2F;code&gt; MUST return &lt;code&gt;false&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST emit an &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; event with the correct values
when a &lt;em&gt;holder&lt;&#x2F;em&gt; authorizes an address as its &lt;em&gt;operator&lt;&#x2F;em&gt; as defined in the
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#authorizedoperator&quot;&gt;&lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; Event&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST emit a &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; event with the correct values
when a &lt;em&gt;holder&lt;&#x2F;em&gt; revokes an address as its &lt;em&gt;operator&lt;&#x2F;em&gt; as defined in the
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#revokedoperator&quot;&gt;&lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; Event&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: A &lt;em&gt;holder&lt;&#x2F;em&gt; MAY authorize an already authorized &lt;em&gt;operator&lt;&#x2F;em&gt;.
An &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; MUST be emitted each time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: A &lt;em&gt;holder&lt;&#x2F;em&gt; MAY revoke an already revoked &lt;em&gt;operator&lt;&#x2F;em&gt;.
A &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; MUST be emitted each time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt; event&lt;&#x2F;strong&gt; &lt;a id=&quot;authorizedoperator&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AuthorizedOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&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;Indicates the authorization of &lt;code&gt;operator&lt;&#x2F;code&gt; as an &lt;em&gt;operator&lt;&#x2F;em&gt; for &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This event MUST NOT be emitted outside of an &lt;em&gt;operator&lt;&#x2F;em&gt; authorization process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which became an &lt;em&gt;operator&lt;&#x2F;em&gt; of &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;holder&lt;&#x2F;code&gt;: Address of a &lt;em&gt;holder&lt;&#x2F;em&gt; which authorized the &lt;code&gt;operator&lt;&#x2F;code&gt; address as an &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; event&lt;&#x2F;strong&gt; &lt;a id=&quot;revokedoperator&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; RevokedOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&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;Indicates the revocation of &lt;code&gt;operator&lt;&#x2F;code&gt; as an &lt;em&gt;operator&lt;&#x2F;em&gt; for &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This event MUST NOT be emitted outside of an &lt;em&gt;operator&lt;&#x2F;em&gt; revocation process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which was revoked as an &lt;em&gt;operator&lt;&#x2F;em&gt; of &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;holder&lt;&#x2F;code&gt;: Address of a &lt;em&gt;holder&lt;&#x2F;em&gt; which revoked the &lt;code&gt;operator&lt;&#x2F;code&gt; address as an &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The &lt;code&gt;defaultOperators&lt;&#x2F;code&gt;, &lt;code&gt;authorizeOperator&lt;&#x2F;code&gt;, &lt;code&gt;revokeOperator&lt;&#x2F;code&gt; and &lt;code&gt;isOperatorFor&lt;&#x2F;code&gt; functions described below
MUST be implemented to manage &lt;em&gt;operators&lt;&#x2F;em&gt;.
Token contracts MAY implement other functions to manage &lt;em&gt;operators&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;defaultOperators&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt; &lt;a id=&quot;defaultOperators&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; defaultOperators&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;Get the list of &lt;em&gt;default operators&lt;&#x2F;em&gt; as defined by the token contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: If the token contract does not have any &lt;em&gt;default operators&lt;&#x2F;em&gt;, this function MUST return an empty list.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;06e48538&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; List of addresses of all the &lt;em&gt;default operators&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;authorizeOperator&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; authorizeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set a third party &lt;code&gt;operator&lt;&#x2F;code&gt; address as an &lt;em&gt;operator&lt;&#x2F;em&gt; of &lt;code&gt;msg.sender&lt;&#x2F;code&gt; to send and burn tokens on its behalf.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;em&gt;holder&lt;&#x2F;em&gt; (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;) is always an &lt;em&gt;operator&lt;&#x2F;em&gt; for itself.
This right SHALL NOT be revoked.
Hence this function MUST &lt;code&gt;revert&lt;&#x2F;code&gt; if it is called to authorize the holder (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;)
as an &lt;em&gt;operator&lt;&#x2F;em&gt; for itself (i.e. if &lt;code&gt;operator&lt;&#x2F;code&gt; is equal to &lt;code&gt;msg.sender&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;959b8c3f&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address to set as an &lt;em&gt;operator&lt;&#x2F;em&gt; for &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;revokeOperator&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; revokeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Remove the right of the &lt;code&gt;operator&lt;&#x2F;code&gt; address to be an &lt;em&gt;operator&lt;&#x2F;em&gt; for &lt;code&gt;msg.sender&lt;&#x2F;code&gt;
and to send and burn tokens on its behalf.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;em&gt;holder&lt;&#x2F;em&gt; (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;) is always an &lt;em&gt;operator&lt;&#x2F;em&gt; for itself.
This right SHALL NOT be revoked.
Hence this function MUST &lt;code&gt;revert&lt;&#x2F;code&gt; if it is called to revoke the holder (&lt;code&gt;msg.sender&lt;&#x2F;code&gt;)
as an &lt;em&gt;operator&lt;&#x2F;em&gt; for itself (i.e., if &lt;code&gt;operator&lt;&#x2F;code&gt; is equal to &lt;code&gt;msg.sender&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;fad8b32a&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address to rescind as an &lt;em&gt;operator&lt;&#x2F;em&gt; for &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;isOperatorFor&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt; &lt;a id=&quot;isOperatorFor&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isOperatorFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; holder&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Indicate whether the &lt;code&gt;operator&lt;&#x2F;code&gt; address is an &lt;em&gt;operator&lt;&#x2F;em&gt; of the &lt;code&gt;holder&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;d95b6371&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which may be an &lt;em&gt;operator&lt;&#x2F;em&gt; of &lt;code&gt;holder&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;holder&lt;&#x2F;code&gt;: Address of a &lt;em&gt;holder&lt;&#x2F;em&gt; which may have the &lt;code&gt;operator&lt;&#x2F;code&gt; address as an &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;returns:&lt;&#x2F;strong&gt; &lt;code&gt;true&lt;&#x2F;code&gt; if &lt;code&gt;operator&lt;&#x2F;code&gt; is an &lt;em&gt;operator&lt;&#x2F;em&gt; of &lt;code&gt;holder&lt;&#x2F;code&gt; and &lt;code&gt;false&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: To know which addresses are &lt;em&gt;operators&lt;&#x2F;em&gt; for a given &lt;em&gt;holder&lt;&#x2F;em&gt;,
one MUST call &lt;code&gt;isOperatorFor&lt;&#x2F;code&gt; with the &lt;em&gt;holder&lt;&#x2F;em&gt; for each &lt;em&gt;default operator&lt;&#x2F;em&gt;
and parse the &lt;code&gt;AuthorizedOperator&lt;&#x2F;code&gt;, and &lt;code&gt;RevokedOperator&lt;&#x2F;code&gt; events for the &lt;em&gt;holder&lt;&#x2F;em&gt; in question.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sending-tokens&quot;&gt;&lt;strong&gt;Sending Tokens&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;When an &lt;em&gt;operator&lt;&#x2F;em&gt; sends an &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens from a &lt;em&gt;holder&lt;&#x2F;em&gt; to a &lt;em&gt;recipient&lt;&#x2F;em&gt;
with the associated &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt;, the token contract MUST apply the following rules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Any authorized &lt;em&gt;operator&lt;&#x2F;em&gt; MAY send tokens to any &lt;em&gt;recipient&lt;&#x2F;em&gt; (except to &lt;code&gt;0x0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of the &lt;em&gt;holder&lt;&#x2F;em&gt; MUST be decreased by the &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of the &lt;em&gt;recipient&lt;&#x2F;em&gt; MUST be increased by the &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of the &lt;em&gt;holder&lt;&#x2F;em&gt; MUST be greater or equal to the &lt;code&gt;amount&lt;&#x2F;code&gt;—such
that its resulting balance is greater or equal to zero (&lt;code&gt;0&lt;&#x2F;code&gt;) after the send.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST emit a &lt;code&gt;Sent&lt;&#x2F;code&gt; event with the correct values as defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#sent&quot;&gt;&lt;code&gt;Sent&lt;&#x2F;code&gt; Event&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;operator&lt;&#x2F;em&gt; MAY include information in the &lt;code&gt;operatorData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST call the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook of the &lt;em&gt;holder&lt;&#x2F;em&gt;
if the &lt;em&gt;holder&lt;&#x2F;em&gt; registers an &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; implementation via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST call the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook of the &lt;em&gt;recipient&lt;&#x2F;em&gt;
if the &lt;em&gt;recipient&lt;&#x2F;em&gt; registers an &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; implementation via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be immutable during the entire send process—hence
the same &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be used to call both hooks and emit the &lt;code&gt;Sent&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The token contract MUST &lt;code&gt;revert&lt;&#x2F;code&gt; when sending in any of the following cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;operator&lt;&#x2F;em&gt; address is not an authorized operator for the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The resulting &lt;em&gt;holder&lt;&#x2F;em&gt; balance or &lt;em&gt;recipient&lt;&#x2F;em&gt; balance after the send
is not a multiple of the &lt;em&gt;granularity&lt;&#x2F;em&gt; defined by the token contract.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;recipient&lt;&#x2F;em&gt; is a contract, and it does not implement the &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; interface via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The address of the &lt;em&gt;holder&lt;&#x2F;em&gt; or the &lt;em&gt;recipient&lt;&#x2F;em&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any of the resulting balances becomes negative, i.e. becomes less than zero (&lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook of the &lt;em&gt;holder&lt;&#x2F;em&gt; &lt;code&gt;revert&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook of the &lt;em&gt;recipient&lt;&#x2F;em&gt; &lt;code&gt;revert&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The token contract MAY send tokens from many &lt;em&gt;holders&lt;&#x2F;em&gt;, to many &lt;em&gt;recipients&lt;&#x2F;em&gt;, or both. In this case:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The previous send rules MUST apply to all the &lt;em&gt;holders&lt;&#x2F;em&gt; and all the &lt;em&gt;recipients&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the balances incremented MUST be equal to the total sent &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the balances decremented MUST be equal to the total sent &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;Sent&lt;&#x2F;code&gt; event MUST be emitted for every &lt;em&gt;holder&lt;&#x2F;em&gt; and &lt;em&gt;recipient&lt;&#x2F;em&gt; pair with the corresponding amount for each pair.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the amounts from the &lt;code&gt;Sent&lt;&#x2F;code&gt; event MUST be equal to the total sent &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Mechanisms such as applying a fee on a send is considered as a send to multiple &lt;em&gt;recipients&lt;&#x2F;em&gt;:
the intended &lt;em&gt;recipient&lt;&#x2F;em&gt; and the fee &lt;em&gt;recipient&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Movements of tokens MAY be chained.
For example, if a contract upon receiving tokens sends them further to another address.
In this case, the previous send rules apply to each send, in order.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Sending an amount of zero (&lt;code&gt;0&lt;&#x2F;code&gt;) tokens is valid and MUST be treated as a regular send.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Implementation Requirement&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The token contract MUST call the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook &lt;em&gt;before&lt;&#x2F;em&gt; updating the state.&lt;&#x2F;li&gt;
&lt;li&gt;The token contract MUST call the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook &lt;em&gt;after&lt;&#x2F;em&gt; updating the state.&lt;br &#x2F;&gt;
I.e., &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; MUST be called first,
then the balances MUST be updated to reflect the send,
and finally &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; MUST be called &lt;em&gt;afterward&lt;&#x2F;em&gt;.
Thus a &lt;code&gt;balanceOf&lt;&#x2F;code&gt; call within &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; returns the balance of the address &lt;em&gt;before&lt;&#x2F;em&gt; the send
and a &lt;code&gt;balanceOf&lt;&#x2F;code&gt; call within &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; returns the balance of the address &lt;em&gt;after&lt;&#x2F;em&gt; the send.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;data&lt;&#x2F;code&gt; field contains information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;—similar
to the data field in a regular ether send transaction.
The &lt;code&gt;tokensToSend()&lt;&#x2F;code&gt; hook, the &lt;code&gt;tokensReceived()&lt;&#x2F;code&gt;, or both
MAY use the information to decide if they wish to reject the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;operatorData&lt;&#x2F;code&gt; field is analogous to the &lt;code&gt;data&lt;&#x2F;code&gt; field except it SHALL be provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST only be provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.
It is intended more for logging purposes and particular cases.
(Examples include payment references, cheque numbers, countersignatures and more.)
In most of the cases the recipient would ignore the &lt;code&gt;operatorData&lt;&#x2F;code&gt;, or at most, it would log the &lt;code&gt;operatorData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Sent&lt;&#x2F;code&gt; event&lt;&#x2F;strong&gt; &lt;a id=&quot;sent&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Sent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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;Indicate a send of &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens from the &lt;code&gt;from&lt;&#x2F;code&gt; address to the &lt;code&gt;to&lt;&#x2F;code&gt; address by the &lt;code&gt;operator&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This event MUST NOT be emitted outside of a send or an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; transfer process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which triggered the send.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens were sent.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens sent.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The &lt;code&gt;send&lt;&#x2F;code&gt; and &lt;code&gt;operatorSend&lt;&#x2F;code&gt; functions described below MUST be implemented to send tokens.
Token contracts MAY implement other functions to send tokens.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;send&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Send the &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens from the address &lt;code&gt;msg.sender&lt;&#x2F;code&gt; to the address &lt;code&gt;to&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;operator&lt;&#x2F;em&gt; and the &lt;em&gt;holder&lt;&#x2F;em&gt; MUST both be the &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;9bd9bbc6&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens to send.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;operatorSend&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; operatorSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Send the &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens on behalf of the address &lt;code&gt;from&lt;&#x2F;code&gt; to the address &lt;code&gt;to&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Reminder&lt;&#x2F;em&gt;: If the &lt;em&gt;operator&lt;&#x2F;em&gt; address is not an authorized operator of the &lt;code&gt;from&lt;&#x2F;code&gt; address,
then the send process MUST &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: &lt;code&gt;from&lt;&#x2F;code&gt; and &lt;code&gt;msg.sender&lt;&#x2F;code&gt; MAY be the same address.
I.e., an address MAY call &lt;code&gt;operatorSend&lt;&#x2F;code&gt; for itself.
This call MUST be equivalent to &lt;code&gt;send&lt;&#x2F;code&gt; with the addition
that the &lt;em&gt;operator&lt;&#x2F;em&gt; MAY specify an explicit value for &lt;code&gt;operatorData&lt;&#x2F;code&gt;
(which cannot be done with the &lt;code&gt;send&lt;&#x2F;code&gt; function).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;62ad1b83&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens are being sent.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens to send.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;minting-tokens&quot;&gt;&lt;strong&gt;Minting Tokens&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Minting tokens is the act of producing new tokens.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; intentionally does not define specific functions to mint tokens.
This intent comes from the wish not to limit the use of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; standard
as the minting process is generally specific for every token.&lt;&#x2F;p&gt;
&lt;p&gt;Nonetheless, the rules below MUST be respected when minting for a &lt;em&gt;recipient&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Tokens MAY be minted for any &lt;em&gt;recipient&lt;&#x2F;em&gt; address (except &lt;code&gt;0x0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The total supply MUST be increased by the amount of tokens minted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of &lt;code&gt;0x0&lt;&#x2F;code&gt; MUST NOT be decreased.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of the &lt;em&gt;recipient&lt;&#x2F;em&gt; MUST be increased by the amount of tokens minted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST emit a &lt;code&gt;Minted&lt;&#x2F;code&gt; event with the correct values as defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#minted&quot;&gt;&lt;code&gt;Minted&lt;&#x2F;code&gt; Event&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST call the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook of the &lt;em&gt;recipient&lt;&#x2F;em&gt;
if the &lt;em&gt;recipient&lt;&#x2F;em&gt; registers an &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; implementation via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be immutable during the entire mint process—hence
the same &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be used to call the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook and emit the &lt;code&gt;Minted&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The token contract MUST &lt;code&gt;revert&lt;&#x2F;code&gt; when minting in any of the following cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The resulting &lt;em&gt;recipient&lt;&#x2F;em&gt; balance after the mint is not a multiple of the &lt;em&gt;granularity&lt;&#x2F;em&gt; defined by the token contract.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;em&gt;recipient&lt;&#x2F;em&gt; is a contract, and it does not implement the &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; interface via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The address of the &lt;em&gt;recipient&lt;&#x2F;em&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook of the &lt;em&gt;recipient&lt;&#x2F;em&gt; &lt;code&gt;revert&lt;&#x2F;code&gt;s.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The initial token supply at the creation of the token contract MUST be considered as minting
for the amount of the initial supply to the address(es) receiving the initial supply.
This means one or more &lt;code&gt;Minted&lt;&#x2F;code&gt; events must be emitted
and the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook of the recipient(s) MUST be called.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatibility requirement&lt;&#x2F;em&gt;:&lt;br &#x2F;&gt;
While a &lt;code&gt;Sent&lt;&#x2F;code&gt; event MUST NOT be emitted when minting,
if the token contract is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; backward compatible,
a &lt;code&gt;Transfer&lt;&#x2F;code&gt; event with the &lt;code&gt;from&lt;&#x2F;code&gt; parameter set to &lt;code&gt;0x0&lt;&#x2F;code&gt; SHOULD be emitted as defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard.&lt;&#x2F;p&gt;
&lt;p&gt;The token contract MAY mint tokens for multiple &lt;em&gt;recipients&lt;&#x2F;em&gt; at once. In this case:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The previous mint rules MUST apply to all the &lt;em&gt;recipients&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the balances incremented MUST be equal to the total minted amount.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;Minted&lt;&#x2F;code&gt; event MUST be emitted for every &lt;em&gt;recipient&lt;&#x2F;em&gt; with the corresponding amount for each &lt;em&gt;recipient&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the amounts from the &lt;code&gt;Minted&lt;&#x2F;code&gt; event MUST be equal to the total minted &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Minting an amount of zero (&lt;code&gt;0&lt;&#x2F;code&gt;) tokens is valid and MUST be treated as a regular mint.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: While during a send or a burn, the data is provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;, it is inapplicable for a mint.
In this case the data MAY be provided by the token contract or the &lt;em&gt;operator&lt;&#x2F;em&gt;,
for example to ensure a successful minting to a &lt;em&gt;holder&lt;&#x2F;em&gt; expecting specific data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;operatorData&lt;&#x2F;code&gt; field contains information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;—similar
to the data field in a regular ether send transaction.
The &lt;code&gt;tokensReceived()&lt;&#x2F;code&gt; hooks MAY use the information to decide if it wish to reject the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Minted&lt;&#x2F;code&gt; event&lt;&#x2F;strong&gt; &lt;a id=&quot;minted&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Minted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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;Indicate the minting of &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens to the &lt;code&gt;to&lt;&#x2F;code&gt; address by the &lt;code&gt;operator&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This event MUST NOT be emitted outside of a mint process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which triggered the mint.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens minted.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided for the &lt;em&gt;recipient&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;burning-tokens&quot;&gt;&lt;strong&gt;Burning Tokens&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Burning tokens is the act of destroying existing tokens.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; explicitly defines two functions to burn tokens (&lt;code&gt;burn&lt;&#x2F;code&gt; and &lt;code&gt;operatorBurn&lt;&#x2F;code&gt;).
These functions facilitate the integration of the burning process in wallets and dapps.
However, the token contract MAY prevent some or all &lt;em&gt;holders&lt;&#x2F;em&gt; from burning tokens for any reason.
The token contract MAY also define other functions to burn tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The rules below MUST be respected when burning the tokens of a &lt;em&gt;holder&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Tokens MAY be burned from any &lt;em&gt;holder&lt;&#x2F;em&gt; address (except &lt;code&gt;0x0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The total supply MUST be decreased by the amount of tokens burned.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of &lt;code&gt;0x0&lt;&#x2F;code&gt; MUST NOT be increased.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of the &lt;em&gt;holder&lt;&#x2F;em&gt; MUST be decreased by amount of tokens burned.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST emit a &lt;code&gt;Burned&lt;&#x2F;code&gt; event with the correct values as defined in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;#burned&quot;&gt;&lt;code&gt;Burned&lt;&#x2F;code&gt; Event&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The token contract MUST call the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook of the &lt;em&gt;holder&lt;&#x2F;em&gt;
if the &lt;em&gt;holder&lt;&#x2F;em&gt; registers an &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; implementation via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be immutable during the entire burn process—hence
the same &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST be used to call the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook and emit the &lt;code&gt;Burned&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The token contract MUST &lt;code&gt;revert&lt;&#x2F;code&gt; when burning in any of the following cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;operator&lt;&#x2F;em&gt; address is not an authorized operator for the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The resulting &lt;em&gt;holder&lt;&#x2F;em&gt; balance after the burn is not a multiple of the &lt;em&gt;granularity&lt;&#x2F;em&gt;
defined by the token contract.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The balance of &lt;em&gt;holder&lt;&#x2F;em&gt; is inferior to the amount of tokens to burn
(i.e., resulting in a negative balance for the &lt;em&gt;holder&lt;&#x2F;em&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The address of the &lt;em&gt;holder&lt;&#x2F;em&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook of the &lt;em&gt;holder&lt;&#x2F;em&gt; &lt;code&gt;revert&lt;&#x2F;code&gt;s.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatibility requirement&lt;&#x2F;em&gt;:&lt;br &#x2F;&gt;
While a &lt;code&gt;Sent&lt;&#x2F;code&gt; event MUST NOT be emitted when burning;
if the token contract is &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; enabled, a &lt;code&gt;Transfer&lt;&#x2F;code&gt; event with the &lt;code&gt;to&lt;&#x2F;code&gt; parameter set to &lt;code&gt;0x0&lt;&#x2F;code&gt; SHOULD be emitted.
The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard does not define the concept of burning tokens, but this is a commonly accepted practice.&lt;&#x2F;p&gt;
&lt;p&gt;The token contract MAY burn tokens for multiple &lt;em&gt;holders&lt;&#x2F;em&gt; at once. In this case:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The previous burn rules MUST apply to each &lt;em&gt;holders&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the balances decremented MUST be equal to the total burned amount.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;Burned&lt;&#x2F;code&gt; event MUST be emitted for every &lt;em&gt;holder&lt;&#x2F;em&gt; with the corresponding amount for each &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The sum of all the amounts from the &lt;code&gt;Burned&lt;&#x2F;code&gt; event MUST be equal to the total burned &lt;code&gt;amount&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Burning an amount of zero (&lt;code&gt;0&lt;&#x2F;code&gt;) tokens is valid and MUST be treated as a regular burn.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;data&lt;&#x2F;code&gt; field contains information provided by the holder—similar
to the data field in a regular ether send transaction.
The &lt;code&gt;tokensToSend()&lt;&#x2F;code&gt; hook, the &lt;code&gt;tokensReceived()&lt;&#x2F;code&gt;, or both
MAY use the information to decide if they wish to reject the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;code&gt;operatorData&lt;&#x2F;code&gt; field is analogous to the &lt;code&gt;data&lt;&#x2F;code&gt; field except it SHALL be provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Burned&lt;&#x2F;code&gt; event&lt;&#x2F;strong&gt; &lt;a id=&quot;burned&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Burned&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Indicate the burning of &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens from the &lt;code&gt;from&lt;&#x2F;code&gt; address by the &lt;code&gt;operator&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This event MUST NOT be emitted outside of a burn process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which triggered the burn.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens were burned.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens burned.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The &lt;code&gt;burn&lt;&#x2F;code&gt; and &lt;code&gt;operatorBurn&lt;&#x2F;code&gt; functions described below MUST be implemented to burn tokens.
Token contracts MAY implement other functions to burn tokens.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;burn&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Burn the &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens from the address &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;operator&lt;&#x2F;em&gt; and the &lt;em&gt;holder&lt;&#x2F;em&gt; MUST both be the &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;fe9d9303&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens to burn.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;operatorBurn&lt;&#x2F;code&gt; function&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; operatorBurn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Burn the &lt;code&gt;amount&lt;&#x2F;code&gt; of tokens on behalf of the address &lt;code&gt;from&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Reminder&lt;&#x2F;em&gt;: If the &lt;em&gt;operator&lt;&#x2F;em&gt; address is not an authorized operator of the &lt;code&gt;from&lt;&#x2F;code&gt; address,
then the burn process MUST &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;fc673c4f&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens will be burned.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens to burn.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: The &lt;em&gt;operator&lt;&#x2F;em&gt; MAY pass any information via &lt;code&gt;operatorData&lt;&#x2F;code&gt;.
The &lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST only be provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: &lt;code&gt;from&lt;&#x2F;code&gt; and &lt;code&gt;msg.sender&lt;&#x2F;code&gt; MAY be the same address.
I.e., an address MAY call &lt;code&gt;operatorBurn&lt;&#x2F;code&gt; for itself.
This call MUST be equivalent to &lt;code&gt;burn&lt;&#x2F;code&gt;
with the addition that the &lt;em&gt;operator&lt;&#x2F;em&gt; MAY specify an explicit value for &lt;code&gt;operatorData&lt;&#x2F;code&gt;
(which cannot be done with the &lt;code&gt;burn&lt;&#x2F;code&gt; function).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;erc777tokenssender-and-the-tokenstosend-hook&quot;&gt;&lt;strong&gt;&lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; And The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; Hook&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook notifies of any request to decrement the balance (send and burn) for a given &lt;em&gt;holder&lt;&#x2F;em&gt;.
Any address (regular or contract) wishing to be notified of token debits from their address
MAY register the address of a contract implementing the &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; interface described below via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is done by calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; registry
with the &lt;em&gt;holder&lt;&#x2F;em&gt; address as the address,
the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt;
(&lt;code&gt;0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895&lt;&#x2F;code&gt;) as the interface hash,
and the address of the contract implementing the &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; as the implementer.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC777TokensSender&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokensToSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: A regular address MAY register a different address—the address of a contract—implementing
the interface on its behalf.
A contract MAY register either its address or the address of another contract
but said address MUST implement the interface on its behalf.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;tokensToSend&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokensToSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notify a request to send or burn (if &lt;code&gt;to&lt;&#x2F;code&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;) an &lt;code&gt;amount&lt;&#x2F;code&gt; tokens from the &lt;code&gt;from&lt;&#x2F;code&gt; address to the &lt;code&gt;to&lt;&#x2F;code&gt; address
by the &lt;code&gt;operator&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This function MUST NOT be called outside of a burn, send or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; transfer process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;75ab9782&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which triggered the balance decrease (through sending or burning).&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens were sent.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens for a send (or &lt;code&gt;0x0&lt;&#x2F;code&gt; for a burn).&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens the &lt;em&gt;holder&lt;&#x2F;em&gt; balance is decreased by.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The following rules apply when calling the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook MUST be called for every send and burn processes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook MUST be called &lt;em&gt;before&lt;&#x2F;em&gt; the state is updated—i.e. &lt;em&gt;before&lt;&#x2F;em&gt; the balance is decremented.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the address which triggered the send or burn process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST be the address of the &lt;em&gt;holder&lt;&#x2F;em&gt; whose tokens are sent or burned.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;to&lt;&#x2F;code&gt; MUST be the address of the &lt;em&gt;recipient&lt;&#x2F;em&gt; which receives the tokens for a send.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;to&lt;&#x2F;code&gt; MUST be &lt;code&gt;0x0&lt;&#x2F;code&gt; for a burn.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;amount&lt;&#x2F;code&gt; MUST be the number of tokens the &lt;em&gt;holder&lt;&#x2F;em&gt; sent or burned.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;data&lt;&#x2F;code&gt; MUST contain the extra information (if any) provided to the send or the burn process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST contain the extra information provided by the address
which triggered the decrease of the balance (if any).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;holder&lt;&#x2F;em&gt; MAY block a send or burn process by &lt;code&gt;revert&lt;&#x2F;code&gt;ing.
(I.e., reject the withdrawal of tokens from its account.)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Multiple &lt;em&gt;holders&lt;&#x2F;em&gt; MAY use the same implementation of &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: An address can register at most one implementation at any given time for all &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; tokens.
Hence the &lt;code&gt;ERC777TokensSender&lt;&#x2F;code&gt; MUST expect to be called by different token contracts.
The &lt;code&gt;msg.sender&lt;&#x2F;code&gt; of the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; call is expected to be the address of the token contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatibility requirement&lt;&#x2F;em&gt;:&lt;br &#x2F;&gt;
This hook takes precedence over &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; and MUST be called (if registered)
when calling &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; event.
When called from a &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the same value as the &lt;code&gt;from&lt;&#x2F;code&gt;.
When called from a &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the address which issued the &lt;code&gt;transferFrom&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;erc777tokensrecipient-and-the-tokensreceived-hook&quot;&gt;&lt;strong&gt;&lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; And The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; Hook&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook notifies of any increment of the balance (send and mint) for a given &lt;em&gt;recipient&lt;&#x2F;em&gt;.
Any address (regular or contract) wishing to be notified of token credits to their address
MAY register the address of a contract implementing the &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; interface described below via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is done by calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function on the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; registry
with the &lt;em&gt;recipient&lt;&#x2F;em&gt; address as the address,
the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt;
(&lt;code&gt;0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b&lt;&#x2F;code&gt;) as the interface hash,
and the address of the contract implementing the &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; as the implementer.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC777TokensRecipient&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the &lt;em&gt;recipient&lt;&#x2F;em&gt; is a contract, which has not registered an &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; implementation;
then the token contract:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MUST &lt;code&gt;revert&lt;&#x2F;code&gt; if the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook is called from a mint or send call.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SHOULD continue processing the transaction
if the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook is called from an ERC-20 &lt;code&gt;transfer&lt;&#x2F;code&gt; or &lt;code&gt;transferFrom&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: A regular address MAY register a different address—the address of a contract—implementing
the interface on its behalf.
A contract MUST register either its address or the address of another contract
but said address MUST implement the interface on its behalf.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;tokensReceived&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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 class=&quot;z-support&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; operatorData&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 class=&quot;z-storage z-type&quot;&gt; external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notify a send or mint (if &lt;code&gt;from&lt;&#x2F;code&gt; is &lt;code&gt;0x0&lt;&#x2F;code&gt;) of &lt;code&gt;amount&lt;&#x2F;code&gt; tokens from the &lt;code&gt;from&lt;&#x2F;code&gt; address to the &lt;code&gt;to&lt;&#x2F;code&gt; address
by the &lt;code&gt;operator&lt;&#x2F;code&gt; address.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: This function MUST NOT be called outside of a mint, send or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; transfer process.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;strong&gt;identifier:&lt;&#x2F;strong&gt; &lt;code&gt;0023de29&lt;&#x2F;code&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;strong&gt;parameters&lt;&#x2F;strong&gt;&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operator&lt;&#x2F;code&gt;: Address which triggered the balance increase (through sending or minting).&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;from&lt;&#x2F;code&gt;: &lt;em&gt;Holder&lt;&#x2F;em&gt; whose tokens were sent (or &lt;code&gt;0x0&lt;&#x2F;code&gt; for a mint).&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: Recipient of the tokens.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;amount&lt;&#x2F;code&gt;: Number of tokens the &lt;em&gt;recipient&lt;&#x2F;em&gt; balance is increased by.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;data&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;holder&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt;: Information provided by the &lt;em&gt;operator&lt;&#x2F;em&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The following rules apply when calling the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook MUST be called for every send and mint processes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook MUST be called &lt;em&gt;after&lt;&#x2F;em&gt; the state is updated—i.e. &lt;em&gt;after&lt;&#x2F;em&gt; the balance is incremented.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the address which triggered the send or mint process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST be the address of the &lt;em&gt;holder&lt;&#x2F;em&gt; whose tokens are sent for a send.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;from&lt;&#x2F;code&gt; MUST be &lt;code&gt;0x0&lt;&#x2F;code&gt; for a mint.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;to&lt;&#x2F;code&gt; MUST be the address of the &lt;em&gt;recipient&lt;&#x2F;em&gt; which receives the tokens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;amount&lt;&#x2F;code&gt; MUST be the number of tokens the &lt;em&gt;recipient&lt;&#x2F;em&gt; sent or minted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;data&lt;&#x2F;code&gt; MUST contain the extra information (if any) provided to the send or the mint process.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;operatorData&lt;&#x2F;code&gt; MUST contain the extra information provided by the address
which triggered the increase of the balance (if any).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;em&gt;holder&lt;&#x2F;em&gt; MAY block a send or mint process by &lt;code&gt;revert&lt;&#x2F;code&gt;ing.
(I.e., reject the reception of tokens.)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Multiple &lt;em&gt;holders&lt;&#x2F;em&gt; MAY use the same implementation of &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: An address can register at most one implementation at any given time for all &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; tokens.
Hence the &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt; MUST expect to be called by different token contracts.
The &lt;code&gt;msg.sender&lt;&#x2F;code&gt; of the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; call is expected to be the address of the token contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; compatibility requirement&lt;&#x2F;em&gt;:&lt;br &#x2F;&gt;
This hook takes precedence over &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; and MUST be called (if registered)
when calling &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; event.
When called from a &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the same value as the &lt;code&gt;from&lt;&#x2F;code&gt;.
When called from a &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;operator&lt;&#x2F;code&gt; MUST be the address which issued the &lt;code&gt;transferFrom&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;note-on-gas-consumption&quot;&gt;&lt;strong&gt;Note On Gas Consumption&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Dapps and wallets SHOULD first estimate the gas required when sending, minting, or burning tokens—using
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;JSON-RPC#eth_estimategas&quot;&gt;&lt;code&gt;eth_estimateGas&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;—to avoid running out of gas during the transaction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;logo&quot;&gt;Logo&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;strong&gt;Image&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;.&#x2F;assets&#x2F;logo&#x2F;png&#x2F;ERC-777-logo-beige-48px.png&quot; alt=&quot;beige logo&quot; &#x2F;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;.&#x2F;assets&#x2F;logo&#x2F;png&#x2F;ERC-777-logo-white-48px.png&quot; alt=&quot;white logo&quot; &#x2F;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;.&#x2F;assets&#x2F;logo&#x2F;png&#x2F;ERC-777-logo-light_grey-48px.png&quot; alt=&quot;light grey logo&quot; &#x2F;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;.&#x2F;assets&#x2F;logo&#x2F;png&#x2F;ERC-777-logo-dark_grey-48px.png&quot; alt=&quot;dark grey logo&quot; &#x2F;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;.&#x2F;assets&#x2F;logo&#x2F;png&#x2F;ERC-777-logo-black-48px.png&quot; alt=&quot;black logo&quot; &#x2F;&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;Color&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;beige&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;white&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;light grey&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;dark grey&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;black&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;Hex&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;code&gt;#C99D66&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;code&gt;#FFFFFF&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;code&gt;#EBEFF0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;code&gt;#3C3C3D&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;code&gt;#000000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The logo MAY be used, modified and adapted to promote valid &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; token implementations
and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; compliant technologies such as wallets and dapps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; token contract authors MAY create a specific logo for their token based on this logo.&lt;&#x2F;p&gt;
&lt;p&gt;The logo MUST NOT be used to advertise, promote or associate in any way technology—such
as tokens—which is not &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; compliant.&lt;&#x2F;p&gt;
&lt;p&gt;The logo for the standard can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;tree&#x2F;master&#x2F;assets&#x2F;eip-777&#x2F;logo&quot;&gt;&lt;code&gt;&#x2F;assets&#x2F;eip-777&#x2F;logo&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; folder in &lt;code&gt;SVG&lt;&#x2F;code&gt; and &lt;code&gt;PNG&lt;&#x2F;code&gt; formats.
The &lt;code&gt;PNG&lt;&#x2F;code&gt; version of the logo offers a few sizes in pixels.
If needed, other sizes MAY be created by converting from &lt;code&gt;SVG&lt;&#x2F;code&gt; into &lt;code&gt;PNG&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The principal intent for this standard is
to solve some of the shortcomings of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; while maintaining backward compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;,
and avoiding the problems and vulnerabilities of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;223&quot;&gt;EIP-223&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below are the rationales for the decisions regarding the main aspects of the standards.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;NOTE&lt;&#x2F;em&gt;: Jacques Dafflon (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&quot;&gt;0xjac&lt;&#x2F;a&gt;), one of the authors of the standard,
conjointly wrote his &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;master-thesis&quot;&gt;master thesis&lt;&#x2F;a&gt; on the standard,
which goes in more details than could reasonably fit directly within the standard,
and can provide further clarifications regarding certain aspects or decisions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lifecycle&quot;&gt;Lifecycle&lt;&#x2F;h3&gt;
&lt;p&gt;More than just sending tokens, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; defines the entire lifecycle of a token,
starting with the minting process, followed by the sending process and terminating with the burn process.&lt;&#x2F;p&gt;
&lt;p&gt;Having a lifecycle clearly defined is important for consistency and accuracy,
especially when value is derived from scarcity.
In contrast when looking at some &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens, a discrepancy can be observed
between the value returned by the &lt;code&gt;totalSupply&lt;&#x2F;code&gt; and the actual circulating supply,
as the standard does not clearly define a process to create and destroy tokens.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data&quot;&gt;Data&lt;&#x2F;h3&gt;
&lt;p&gt;The mint, send and burn processes can all make use of a &lt;code&gt;data&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; fields
which are passed to any movement (mint, send or burn).
Those fields may be empty for simple use cases,
or they may contain valuable information related to the movement of tokens,
similar to information attached to a bank transfer by the sender or the bank itself.&lt;&#x2F;p&gt;
&lt;p&gt;The use of a &lt;code&gt;data&lt;&#x2F;code&gt; field is equally present in other standard proposals such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;223&quot;&gt;EIP-223&lt;&#x2F;a&gt;,
and was requested by multiple members of the community who reviewed this standard.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hooks&quot;&gt;Hooks&lt;&#x2F;h3&gt;
&lt;p&gt;In most cases, &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; requires two calls to safely transfer tokens to a contract without locking them.
A call from the sender, using the &lt;code&gt;approve&lt;&#x2F;code&gt; function
and a call from the recipient using &lt;code&gt;transferFrom&lt;&#x2F;code&gt;.
Furthermore, this requires extra communication between the parties which is not clearly defined.
Finally, holders can get confused between &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;approve&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;transferFrom&lt;&#x2F;code&gt;.
Using the former to transfer tokens to a contract will most likely result in locked tokens.&lt;&#x2F;p&gt;
&lt;p&gt;Hooks allow streamlining of the sending process and offer a single way to send tokens to any recipient.
Thanks to the &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook, contracts are able to react and prevent locking tokens upon reception.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;greater-control-for-holders&quot;&gt;&lt;strong&gt;Greater Control For Holders&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook also allows holders to reject the reception of some tokens.
This gives greater control to holders who can accept or reject incoming tokens based on some parameters,
for example located in the &lt;code&gt;data&lt;&#x2F;code&gt; or &lt;code&gt;operatorData&lt;&#x2F;code&gt; fields.&lt;&#x2F;p&gt;
&lt;p&gt;Following the same intentions and based on suggestions from the community,
the &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; hook was added to give control over and prevent the movement of outgoing tokens.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;erc-1820-registry&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; Registry&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; Registry allows holders to register their hooks.
Other alternatives were examined beforehand to link hooks and holders.&lt;&#x2F;p&gt;
&lt;p&gt;The first was for hooks to be defined at the sender&#x27;s or recipient&#x27;s address.
This approach is similar to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;223&quot;&gt;EIP-223&lt;&#x2F;a&gt; which proposes a &lt;code&gt;tokenFallback&lt;&#x2F;code&gt; function on recipient contracts
to be called when receiving tokens,
but improves on it by relying on &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;ERC-165&lt;&#x2F;a&gt; for interface detection.
While straightforward to implement, this approach imposes several limitations.
In particular, the sender and recipient must be contracts in order to provide their implementation of the hooks.
Preventing externally owned addresses to benefit from hooks.
Existing contracts have a strong probability not to be compatible,
as they undoubtedly were unaware and do not define the new hooks.
Consequently existing smart contract infrastructure such as multisig wallets
which potentially hold large amounts of ether and tokens would need to be migrated to new updated contracts.&lt;&#x2F;p&gt;
&lt;p&gt;The second approach considered was to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;672&quot;&gt;ERC-672&lt;&#x2F;a&gt; which offered pseudo-introspection for addresses using reverse-ENS.
However, this approach relied heavily on ENS, on top of which reverse lookup would need to be implemented.
Analysis of this approach promptly revealed a certain degree of complexity and security concerns
which would transcend the benefits of approach.&lt;&#x2F;p&gt;
&lt;p&gt;The third solution—used in this standard—is to rely on a unique registry
where any address can register the addresses of contracts implementing the hooks on its behalf.
This approach has the advantage that externally owned accounts and contracts can benefit from hooks,
including existing contracts which can rely on hooks deployed on proxy contracts.&lt;&#x2F;p&gt;
&lt;p&gt;The decision was made to keep this registry in a separate EIP,
as to not over complicate this standard.
More importantly, the registry is designed in a flexible fashion,
such that other EIPs and smart contract infrastructures can benefit from it
for their own use cases, outside the realm of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; and tokens.
The first proposal for this registry was &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt;.
Unfortunately, issues emanating from upgrades in the Solidity language to versions 0.5 and above
resulted in a bug in a separated part of the registry, which required changes.
This was discovered right after the last call period.
Attempts made to avoid creating a separate EIP, such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;pull&#x2F;1758&quot;&gt;ERC-820a&lt;&#x2F;a&gt;, were rejected.
Hence the standard for the registry used for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; became &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;820&#x2F;&quot;&gt;ERC-820&lt;&#x2F;a&gt; are functionally equivalent. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; simply contains the fix for newer versions of Solidity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;operators-1&quot;&gt;Operators&lt;&#x2F;h3&gt;
&lt;p&gt;The standard defines the concept of operators as any address which moves tokens.
While intuitively every address moves its own tokens,
separating the concepts of holder and operator allows for greater flexibility.
Primarily, this originates from the fact that the standard defines a mechanism for holders
to let other addresses become their operators.
Moreover, unlike the approve calls in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; where the role of an approved address is not clearly defined,
&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; details the intent of and interactions with operators,
including an obligation for operators to be approved,
and an irrevocable right for any holder to revoke operators.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;default-operators&quot;&gt;&lt;strong&gt;Default Operators&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Default operators were added based on community demand for pre-approved operators.
That is operators which are approved for all holders by default.
For obvious security reasons, the list of default operators is defined at the token contract creation time,
and cannot be changed.
Any holder still has the right to revoke default operators.
One of the obvious advantages of default operators is to allow ether-less movements of tokens.
Default operators offer other usability advantages,
such as allowing token providers to offer functionality in a modular way,
and to reduce the complexity for holders to use features provided through operators.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backward-compatibility&quot;&gt;Backward Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP does not introduce backward incompatibilities and is backward compatible with the older &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token standard.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP does not use &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; and uses &lt;code&gt;send&lt;&#x2F;code&gt; and &lt;code&gt;operatorSend&lt;&#x2F;code&gt;
to avoid confusion and mistakes when deciphering which token standard is being used.&lt;&#x2F;p&gt;
&lt;p&gt;This standard allows the implementation of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; functions &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, &lt;code&gt;approve&lt;&#x2F;code&gt; and &lt;code&gt;allowance&lt;&#x2F;code&gt;
alongside to make a token fully compatible with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The token MAY implement &lt;code&gt;decimals()&lt;&#x2F;code&gt; for backward compatibility with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.
If implemented, it MUST always return &lt;code&gt;18&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore a token contract MAY implement both &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; in parallel.
The specification of the &lt;code&gt;view&lt;&#x2F;code&gt; functions (such as &lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;symbol&lt;&#x2F;code&gt;, &lt;code&gt;balanceOf&lt;&#x2F;code&gt;, &lt;code&gt;totalSupply&lt;&#x2F;code&gt;) and internal data
(such as the mapping of balances) overlap without problems.
Note however that the following functions are mandatory in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; and MUST be implemented:
&lt;code&gt;name&lt;&#x2F;code&gt;, &lt;code&gt;symbol&lt;&#x2F;code&gt; &lt;code&gt;balanceOf&lt;&#x2F;code&gt; and &lt;code&gt;totalSupply&lt;&#x2F;code&gt;
(&lt;code&gt;decimals&lt;&#x2F;code&gt; is not part of the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; standard).&lt;&#x2F;p&gt;
&lt;p&gt;The state-modifying functions from both standards are decoupled and can operate independently from each other.
Note that &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; functions SHOULD be limited to only being called from old contracts.&lt;&#x2F;p&gt;
&lt;p&gt;If the token implements &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;,
it MUST register the &lt;code&gt;ERC20Token&lt;&#x2F;code&gt; interface with its own address via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;.
This is done by calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; function on the ERC-1820 registry
with the token contract address as both the address and the implementer
and the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC20Token&lt;&#x2F;code&gt; (&lt;code&gt;0xaea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a&lt;&#x2F;code&gt;)
as the interface hash.&lt;&#x2F;p&gt;
&lt;p&gt;If the contract has a switch to enable or disable ERC-20 functions, every time the switch is triggered,
the token MUST register or unregister the &lt;code&gt;ERC20Token&lt;&#x2F;code&gt; interface for its own address accordingly via ERC1820.
Unregistering implies calling the &lt;code&gt;setInterfaceImplementer&lt;&#x2F;code&gt; with the token contract address as the address,
the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of &lt;code&gt;ERC20Token&lt;&#x2F;code&gt; as the interface hash and &lt;code&gt;0x0&lt;&#x2F;code&gt; as the implementer.
(See &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;#set-an-interface-for-an-address&quot;&gt;Set An Interface For An Address&lt;&#x2F;a&gt; in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt; for more details.)&lt;&#x2F;p&gt;
&lt;p&gt;The difference for new contracts implementing &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; is that
&lt;code&gt;tokensToSend&lt;&#x2F;code&gt; and &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hooks take precedence over &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;.
Even with an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;transferFrom&lt;&#x2F;code&gt; call, the token contract MUST check via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;
if the &lt;code&gt;from&lt;&#x2F;code&gt; and the &lt;code&gt;to&lt;&#x2F;code&gt; address implement &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; and &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook respectively.
If any hook is implemented, it MUST be called.
Note that when calling &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;transfer&lt;&#x2F;code&gt; on a contract, if the contract does not implement &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;,
the &lt;code&gt;transfer&lt;&#x2F;code&gt; call SHOULD still be accepted even if this means the tokens will probably be locked.&lt;&#x2F;p&gt;
&lt;p&gt;The table below summarizes the different actions the token contract MUST take
when sending, minting and transferring token via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;th align=&quot;right&quot;&gt;ERC1820&lt;&#x2F;th&gt;
    &lt;th&gt;&lt;code&gt;to&lt;&#x2F;code&gt; address&lt;&#x2F;th&gt;
    &lt;th align=&quot;center&quot;&gt;ERC777 Sending And Minting&lt;&#x2F;th&gt;
    &lt;th align=&quot;center&quot;&gt;ERC20 &lt;code&gt;transfer&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;transferFrom&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;
  &lt;&#x2F;tr&gt;
  &lt;tr&gt;
    &lt;td rowspan=&quot;2&quot; align=&quot;right&quot;&gt;
      &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt;&lt;br&#x2F;&gt;registered
    &lt;&#x2F;td&gt;
    &lt;td&gt;regular address&lt;&#x2F;td&gt;
    &lt;td colspan=&quot;2&quot; rowspan=&quot;2&quot; align=&quot;center&quot;&gt;
      MUST call &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;
    &lt;&#x2F;td&gt;
  &lt;&#x2F;tr&gt;
  &lt;tr&gt;
    &lt;td&gt;contract&lt;&#x2F;td&gt;
  &lt;&#x2F;tr&gt;
  &lt;tr&gt;
    &lt;td rowspan=&quot;2&quot; align=&quot;right&quot;&gt;
      &lt;code&gt;ERC777TokensRecipient&lt;&#x2F;code&gt;&lt;br&#x2F;&gt;not registered
    &lt;&#x2F;td&gt;
    &lt;td&gt;regular address&lt;&#x2F;td&gt;
    &lt;td colspan=&quot;2&quot; align=&quot;center&quot;&gt;continue&lt;&#x2F;td&gt;
  &lt;&#x2F;tr&gt;
  &lt;tr&gt;
    &lt;td&gt;contract&lt;&#x2F;td&gt;
    &lt;td align=&quot;center&quot;&gt;MUST &lt;code&gt;revert&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
    &lt;td align=&quot;center&quot;&gt;SHOULD continue&lt;sup&gt;&lt;a id=&quot;continue-footnote-backlink&quot; href=&quot;#continue-footnote&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;
  &lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;#continue-footnote-backlink&quot;&gt;&lt;small id=&quot;continue-footnote&quot;&gt;1.&lt;&#x2F;small&gt;&lt;&#x2F;a&gt;
&lt;small&gt;The transaction SHOULD continue for clarity as ERC20 is not aware of hooks.&lt;&#x2F;small&gt;&lt;br &#x2F;&gt;
&lt;small&gt;However, this can result in accidentally locked tokens.&lt;&#x2F;small&gt;
&lt;small&gt;If avoiding accidentally locked tokens is paramount, the transaction MAY &lt;code&gt;revert&lt;&#x2F;code&gt;.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;There is no particular action to take if &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; is not implemented.
The movement MUST proceed and only be canceled if another condition is not respected
such as lack of funds or a &lt;code&gt;revert&lt;&#x2F;code&gt; in &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; (if present).&lt;&#x2F;p&gt;
&lt;p&gt;During a send, mint and burn, the respective &lt;code&gt;Sent&lt;&#x2F;code&gt;, &lt;code&gt;Minted&lt;&#x2F;code&gt; and &lt;code&gt;Burned&lt;&#x2F;code&gt; events MUST be emitted.
Furthermore, if the token contract declares that it implements &lt;code&gt;ERC20Token&lt;&#x2F;code&gt; via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;1820&#x2F;&quot;&gt;ERC-1820&lt;&#x2F;a&gt;,
the token contract SHOULD emit a &lt;code&gt;Transfer&lt;&#x2F;code&gt; event for minting and burning
and MUST emit a &lt;code&gt;Transfer&lt;&#x2F;code&gt; event for sending (as specified in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard).
During an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;transfer&lt;&#x2F;code&gt; or &lt;code&gt;transferFrom&lt;&#x2F;code&gt; functions, a valid &lt;code&gt;Sent&lt;&#x2F;code&gt; event MUST be emitted.&lt;&#x2F;p&gt;
&lt;p&gt;Hence for any movement of tokens, two events MAY be emitted:
an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; &lt;code&gt;Transfer&lt;&#x2F;code&gt; and an &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;777&#x2F;&quot;&gt;ERC-777&lt;&#x2F;a&gt; &lt;code&gt;Sent&lt;&#x2F;code&gt;, &lt;code&gt;Minted&lt;&#x2F;code&gt; or &lt;code&gt;Burned&lt;&#x2F;code&gt; (depending on the type of movement).
Third-party developers MUST be careful not to consider both events as separate movements.
As a general rule, if an application considers the token as an ERC20 token,
then only the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event MUST be taken into account.
If the application considers the token as an ERC777 token,
then only the &lt;code&gt;Sent&lt;&#x2F;code&gt;, &lt;code&gt;Minted&lt;&#x2F;code&gt; and &lt;code&gt;Burned&lt;&#x2F;code&gt; events MUST be considered.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC777&quot;&gt;repository with the reference implementation&lt;&#x2F;a&gt; contains all the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC777&#x2F;blob&#x2F;master&#x2F;test&#x2F;ReferenceToken.test.js&quot;&gt;tests&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The GitHub repository &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC777&quot;&gt;0xjac&#x2F;ERC777&lt;&#x2F;a&gt; contains the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xjac&#x2F;ERC777&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;examples&#x2F;ReferenceToken.sol&quot;&gt;reference implementation&lt;&#x2F;a&gt;.
The reference implementation is also available via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;erc777&quot;&gt;npm&lt;&#x2F;a&gt; and can be installed with &lt;code&gt;npm install erc777&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Typed structured data hashing and signing</title>
        <published>2017-09-12T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Remco Bloemen</name><uri>https://github.com/Recmo</uri>
	</author>
	
	<author>
		<name>Leonid Logvinov</name><uri>https://github.com/LogvinovLeon</uri>
	</author>
	
	<author>
		<name>Jacob Evans</name><uri>https://github.com/dekz</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/712/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-712-eth-signtypeddata-as-a-standard-for-machine-verifiable-and-human-readable-typed-data-signing/397" />
        

        <id>https://wg-eips.ritovision.com/712/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:712"
            label="EIP-712" />
        

        
        

        
        <summary type="html">A procedure for hashing and signing of typed structured data as opposed to just bytestrings.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/712/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This is a standard for hashing and signing of typed structured data as opposed to just bytestrings. It includes a&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;theoretical framework for correctness of encoding functions,&lt;&#x2F;li&gt;
&lt;li&gt;specification of structured data similar to and compatible with Solidity structs,&lt;&#x2F;li&gt;
&lt;li&gt;safe hashing algorithm for instances of those structures,&lt;&#x2F;li&gt;
&lt;li&gt;safe inclusion of those instances in the set of signable messages,&lt;&#x2F;li&gt;
&lt;li&gt;an extensible mechanism for domain separation,&lt;&#x2F;li&gt;
&lt;li&gt;new RPC call &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt;, and&lt;&#x2F;li&gt;
&lt;li&gt;an optimized implementation of the hashing algorithm in EVM.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It does not include replay protection.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Signing data is a solved problem if all we care about are bytestrings. Unfortunately in the real world we care about complex meaningful messages. Hashing structured data is non-trivial and errors result in loss of the security properties of the system.&lt;&#x2F;p&gt;
&lt;p&gt;As such, the adage &quot;don&#x27;t roll your own crypto&quot; applies. Instead, a peer-reviewed well-tested standard method needs to be used. This EIP aims to be that standard.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP aims to improve the usability of off-chain message signing for use on-chain. We are seeing growing adoption of off-chain message signing as it saves gas and reduces the number of transactions on the blockchain. Currently signed messages are an opaque hex string displayed to the user with little context about the items that make up the message.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;.&#x2F;assets&#x2F;eth_sign.png&quot; alt=&quot;eth_sign screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here we outline a scheme to encode data along with its structure which allows it to be displayed to the user for verification when signing. Below is an example of what a user could be shown when signing a message according to the present proposal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;.&#x2F;assets&#x2F;eth_signTypedData.png&quot; alt=&quot;eth_signTypedData screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The set of signable messages is extended from transactions and bytestrings &lt;code&gt;𝕋 ∪ 𝔹⁸ⁿ&lt;&#x2F;code&gt; to also include structured data &lt;code&gt;𝕊&lt;&#x2F;code&gt;. The new set of signable messages is thus &lt;code&gt;𝕋 ∪ 𝔹⁸ⁿ ∪ 𝕊&lt;&#x2F;code&gt;. They are encoded to bytestrings suitable for hashing and signing as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;encode(transaction : 𝕋) = RLP_encode(transaction)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;encode(message : 𝔹⁸ⁿ) = &quot;\x19Ethereum Signed Message:\n&quot; ‖ len(message) ‖ message&lt;&#x2F;code&gt; where &lt;code&gt;len(message)&lt;&#x2F;code&gt; is the &lt;em&gt;non-zero-padded&lt;&#x2F;em&gt; ascii-decimal encoding of the number of bytes in &lt;code&gt;message&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = &quot;\x19\x01&quot; ‖ domainSeparator ‖ hashStruct(message)&lt;&#x2F;code&gt; where &lt;code&gt;domainSeparator&lt;&#x2F;code&gt; and &lt;code&gt;hashStruct(message)&lt;&#x2F;code&gt; are defined below.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This encoding is deterministic because the individual components are. The encoding is injective because the three cases always differ in first byte. (&lt;code&gt;RLP_encode(transaction)&lt;&#x2F;code&gt; does not start with &lt;code&gt;\x19&lt;&#x2F;code&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;The encoding is compliant with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;ERC-191&lt;&#x2F;a&gt;. The &#x27;version byte&#x27; is fixed to &lt;code&gt;0x01&lt;&#x2F;code&gt;, the &#x27;version specific data&#x27; is the 32-byte domain separator &lt;code&gt;domainSeparator&lt;&#x2F;code&gt; and the &#x27;data to sign&#x27; is the 32-byte &lt;code&gt;hashStruct(message)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-typed-structured-data-s&quot;&gt;Definition of typed structured data &lt;code&gt;𝕊&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;To define the set of all structured data, we start with defining acceptable types. Like ABIv2 these are closely related to Solidity types. It is illustrative to adopt Solidity notation to explain the definitions. The standard is specific to the Ethereum Virtual Machine, but aims to be agnostic to higher level languages. Example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Mail&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span&gt; contents&lt;&#x2F;span&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;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: A &lt;em&gt;struct type&lt;&#x2F;em&gt; has valid identifier as name and contains zero or more member variables. Member variables have a member type and a name.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: A &lt;em&gt;member type&lt;&#x2F;em&gt; can be either an atomic type, a dynamic type or a reference type.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: The &lt;em&gt;atomic types&lt;&#x2F;em&gt; are &lt;code&gt;bytes1&lt;&#x2F;code&gt; to &lt;code&gt;bytes32&lt;&#x2F;code&gt;, &lt;code&gt;uint8&lt;&#x2F;code&gt; to &lt;code&gt;uint256&lt;&#x2F;code&gt;, &lt;code&gt;int8&lt;&#x2F;code&gt; to &lt;code&gt;int256&lt;&#x2F;code&gt;, &lt;code&gt;bool&lt;&#x2F;code&gt; and &lt;code&gt;address&lt;&#x2F;code&gt;. These correspond to their definition in Solidity. Note that there are no aliases &lt;code&gt;uint&lt;&#x2F;code&gt; and &lt;code&gt;int&lt;&#x2F;code&gt;. Note that contract addresses are always plain &lt;code&gt;address&lt;&#x2F;code&gt;. Fixed point numbers are not supported by the standard. Future versions of this standard may add new atomic types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: The &lt;em&gt;dynamic types&lt;&#x2F;em&gt; are &lt;code&gt;bytes&lt;&#x2F;code&gt; and &lt;code&gt;string&lt;&#x2F;code&gt;. These are like the atomic types for the purpose of type declaration, but their treatment in encoding is different.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: The &lt;em&gt;reference types&lt;&#x2F;em&gt; are arrays and structs. Arrays are either fixed size or dynamic and denoted by &lt;code&gt;Type[n]&lt;&#x2F;code&gt; or &lt;code&gt;Type[]&lt;&#x2F;code&gt; respectively. Structs are references to other structs by their name. The standard supports recursive struct types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt;: The set of structured typed data &lt;code&gt;𝕊&lt;&#x2F;code&gt; contains all the instances of all the struct types.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-hashstruct&quot;&gt;Definition of &lt;code&gt;hashStruct&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;hashStruct&lt;&#x2F;code&gt; function is defined as&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))&lt;&#x2F;code&gt; where &lt;code&gt;typeHash = keccak256(encodeType(typeOf(s)))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: The &lt;code&gt;typeHash&lt;&#x2F;code&gt; is a constant for a given struct type and does not need to be runtime computed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-encodetype&quot;&gt;Definition of &lt;code&gt;encodeType&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The type of a struct is encoded as &lt;code&gt;name ‖ &quot;(&quot; ‖ member₁ ‖ &quot;,&quot; ‖ member₂ ‖ &quot;,&quot; ‖ … ‖ memberₙ &quot;)&quot;&lt;&#x2F;code&gt; where each member is written as &lt;code&gt;type ‖ &quot; &quot; ‖ name&lt;&#x2F;code&gt;. For example, the above &lt;code&gt;Mail&lt;&#x2F;code&gt; struct is encoded as &lt;code&gt;Mail(address from,address to,string contents)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the struct type references other struct types (and these in turn reference even more struct types), then the set of referenced struct types is collected, sorted by name and appended to the encoding. An example encoding is &lt;code&gt;Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-encodedata&quot;&gt;Definition of &lt;code&gt;encodeData&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The encoding of a struct instance is &lt;code&gt;enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)&lt;&#x2F;code&gt;, i.e. the concatenation of the encoded member values in the order that they appear in the type. Each encoded member value is exactly 32-byte long.&lt;&#x2F;p&gt;
&lt;p&gt;The atomic values are encoded as follows: Boolean &lt;code&gt;false&lt;&#x2F;code&gt; and &lt;code&gt;true&lt;&#x2F;code&gt; are encoded as &lt;code&gt;uint256&lt;&#x2F;code&gt; values &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;1&lt;&#x2F;code&gt; respectively. Addresses are encoded as &lt;code&gt;uint160&lt;&#x2F;code&gt;. Integer values are sign-extended to 256-bit and encoded in big endian order. &lt;code&gt;bytes1&lt;&#x2F;code&gt; to &lt;code&gt;bytes31&lt;&#x2F;code&gt; are arrays with a beginning (index &lt;code&gt;0&lt;&#x2F;code&gt;) and an end (index &lt;code&gt;length - 1&lt;&#x2F;code&gt;), they are zero-padded at the end to &lt;code&gt;bytes32&lt;&#x2F;code&gt; and encoded in beginning to end order. This corresponds to their encoding in ABI v1 and v2.&lt;&#x2F;p&gt;
&lt;p&gt;The dynamic values &lt;code&gt;bytes&lt;&#x2F;code&gt; and &lt;code&gt;string&lt;&#x2F;code&gt; are encoded as a &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of their contents.&lt;&#x2F;p&gt;
&lt;p&gt;The array values are encoded as the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of the concatenated &lt;code&gt;encodeData&lt;&#x2F;code&gt; of their contents (i.e. the encoding of &lt;code&gt;SomeType[5]&lt;&#x2F;code&gt; is identical to that of a struct containing five members of type &lt;code&gt;SomeType&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The struct values are encoded recursively as &lt;code&gt;hashStruct(value)&lt;&#x2F;code&gt;. This is undefined for cyclical data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-domainseparator&quot;&gt;Definition of &lt;code&gt;domainSeparator&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;domainSeparator &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashStruct&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;eip712Domain&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;where the type of &lt;code&gt;eip712Domain&lt;&#x2F;code&gt; is a struct named &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; with one or more of the below fields. Protocol designers only need to include the fields that make sense for their signing domain. Unused fields are left out of the struct type.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;string name&lt;&#x2F;code&gt; the user readable name of signing domain, i.e. the name of the DApp or the protocol.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;string version&lt;&#x2F;code&gt; the current major version of the signing domain. Signatures from different versions are not compatible.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;uint256 chainId&lt;&#x2F;code&gt; the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; chain id. The user-agent &lt;em&gt;should&lt;&#x2F;em&gt; refuse signing if it does not match the currently active chain.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;address verifyingContract&lt;&#x2F;code&gt; the address of the contract that will verify the signature. The user-agent &lt;em&gt;may&lt;&#x2F;em&gt; do contract specific phishing prevention.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bytes32 salt&lt;&#x2F;code&gt; a disambiguating salt for the protocol. This can be used as a domain separator of last resort.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Future extensions to this standard can add new fields with new user-agent behaviour constraints. User-agents are free to use the provided information to inform&#x2F;warn users or refuse signing. Dapp implementers should not add private fields, new fields should be proposed through the EIP process.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; fields should be the order as above, skipping any absent fields. Future field additions must be in alphabetical order and come after the above fields. User-agents should accept fields in any order as specified by the &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; type.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specification-of-the-eth-signtypeddata-json-rpc&quot;&gt;Specification of the &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt; JSON RPC&lt;&#x2F;h3&gt;
&lt;p&gt;The method &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt; is added to the Ethereum JSON-RPC. The method parallels &lt;code&gt;eth_sign&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;eth-signtypeddata&quot;&gt;eth_signTypedData&lt;&#x2F;h4&gt;
&lt;p&gt;The sign method calculates an Ethereum specific signature with: &lt;code&gt;sign(keccak256(&quot;\x19\x01&quot; ‖ domainSeparator ‖ hashStruct(message)))&lt;&#x2F;code&gt;, as defined above.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: the address to sign with must be unlocked.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Address&lt;&#x2F;code&gt; - 20 Bytes - Address of the account that will sign the messages.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TypedData&lt;&#x2F;code&gt; - Typed structured data to be signed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Typed data is a JSON object containing type information, domain separator parameters and the message object. Below is the json-schema definition for &lt;code&gt;TypedData&lt;&#x2F;code&gt; param.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&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 class=&quot;z-entity z-name&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-entity z-name&quot;&gt;  properties&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    types&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;      type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-entity z-name&quot;&gt;      properties&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        EIP712Domain&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-entity z-name&quot;&gt;      additionalProperties&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-entity z-name&quot;&gt;        items&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;          type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-entity z-name&quot;&gt;          properties&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&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 class=&quot;z-entity z-name&quot;&gt;          required&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&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;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;      required&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;EIP712Domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&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 class=&quot;z-entity z-name&quot;&gt;    primaryType&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    domain&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;    message&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&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 class=&quot;z-entity z-name&quot;&gt;  required&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;types&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;primaryType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;returns&quot;&gt;Returns&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;code&gt;DATA&lt;&#x2F;code&gt;: Signature. As in &lt;code&gt;eth_sign&lt;&#x2F;code&gt; it is a hex encoded 65 byte array starting with &lt;code&gt;0x&lt;&#x2F;code&gt;. It encodes the &lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; and &lt;code&gt;v&lt;&#x2F;code&gt; parameters from appendix F of the yellow paper in big-endian format. Bytes 0...32 contain the &lt;code&gt;r&lt;&#x2F;code&gt; parameter, bytes 32...64 the &lt;code&gt;s&lt;&#x2F;code&gt; parameter and the last byte the &lt;code&gt;v&lt;&#x2F;code&gt; parameter. Note that the &lt;code&gt;v&lt;&#x2F;code&gt; parameter includes the chain id as specified in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;example&quot;&gt;Example&lt;&#x2F;h5&gt;
&lt;p&gt;Request:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{&amp;quot;jsonrpc&amp;quot;:&amp;quot;2.0&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;eth_signTypedData&amp;quot;,&amp;quot;params&amp;quot;:[&amp;quot;0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826&amp;quot;, {&amp;quot;types&amp;quot;:{&amp;quot;EIP712Domain&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;name&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;chainId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;verifyingContract&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;Person&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;name&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;wallet&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;Mail&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;from&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Person&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Person&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;contents&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;}]},&amp;quot;primaryType&amp;quot;:&amp;quot;Mail&amp;quot;,&amp;quot;domain&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;Ether Mail&amp;quot;,&amp;quot;version&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;chainId&amp;quot;:1,&amp;quot;verifyingContract&amp;quot;:&amp;quot;0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC&amp;quot;},&amp;quot;message&amp;quot;:{&amp;quot;from&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;Cow&amp;quot;,&amp;quot;wallet&amp;quot;:&amp;quot;0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826&amp;quot;},&amp;quot;to&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;Bob&amp;quot;,&amp;quot;wallet&amp;quot;:&amp;quot;0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB&amp;quot;},&amp;quot;contents&amp;quot;:&amp;quot;Hello, Bob!&amp;quot;}}],&amp;quot;id&amp;quot;:1}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Result:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;jsonrpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;An example how to use Solidity ecrecover to verify the signature calculated with &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt; can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;.&#x2F;assets&#x2F;Example.js&quot;&gt;Example.js&lt;&#x2F;a&gt;. The contract is deployed on the testnet Ropsten and Rinkeby.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;personal-signtypeddata&quot;&gt;personal_signTypedData&lt;&#x2F;h4&gt;
&lt;p&gt;There also should be a corresponding &lt;code&gt;personal_signTypedData&lt;&#x2F;code&gt; method which accepts the password for an account as the last argument.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specification-of-the-web3-api&quot;&gt;Specification of the Web3 API&lt;&#x2F;h3&gt;
&lt;p&gt;Two methods are added to Web3.js version 1 that parallel the &lt;code&gt;web3.eth.sign&lt;&#x2F;code&gt; and &lt;code&gt;web3.eth.personal.sign&lt;&#x2F;code&gt; methods.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;web3-eth-signtypeddata&quot;&gt;web3.eth.signTypedData&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;web3&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;eth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;signTypedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;typedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; callback&lt;&#x2F;span&gt;&lt;span&gt;]&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;Signs typed data using a specific account. This account needs to be unlocked.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;parameters-1&quot;&gt;Parameters&lt;&#x2F;h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Object&lt;&#x2F;code&gt; - Domain separator and typed data to sign. Structured according to the JSON-Schema specified above in the &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt; JSON RPC call.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;String|Number&lt;&#x2F;code&gt; - Address to sign data with. Or an address or index of a local wallet in :ref:&lt;code&gt;web3.eth.accounts.wallet &amp;lt;eth_accounts_wallet&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Function&lt;&#x2F;code&gt; - (optional) Optional callback, returns an error object as first parameter and the result as second.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: The 2. &lt;code&gt;address&lt;&#x2F;code&gt; parameter can also be an address or index from the &lt;code&gt;web3.eth.accounts.wallet &amp;lt;eth_accounts_wallet&amp;gt;&lt;&#x2F;code&gt;. It will then sign locally using the private key of this account.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;returns-1&quot;&gt;Returns&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;code&gt;Promise&lt;&#x2F;code&gt; returns &lt;code&gt;String&lt;&#x2F;code&gt; - The signature as returned by &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;example-1&quot;&gt;Example&lt;&#x2F;h5&gt;
&lt;p&gt;See the &lt;code&gt;eth_signTypedData&lt;&#x2F;code&gt; JSON-API example above for the value of &lt;code&gt;typedData&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;web3&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;eth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;signTypedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;typedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;web3-eth-personal-signtypeddata&quot;&gt;web3.eth.personal.signTypedData&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;web3&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;eth&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;personal&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;signTypedData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;typedData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; password&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; callback&lt;&#x2F;span&gt;&lt;span&gt;]&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;Identical to &lt;code&gt;web3.eth.signTypedData&lt;&#x2F;code&gt; except for an additional &lt;code&gt;password&lt;&#x2F;code&gt; parameter analogous to &lt;code&gt;web3.eth.personal.sign&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;encode&lt;&#x2F;code&gt; function is extended with a new case for the new types. The first byte of the encoding distinguishes the cases. For the same reason it is not safe to start immediately with the domain separator or a &lt;code&gt;typeHash&lt;&#x2F;code&gt;. While hard, it may be possible to construct a &lt;code&gt;typeHash&lt;&#x2F;code&gt; that also happens to be a prefix of a valid RLP encoded transaction.&lt;&#x2F;p&gt;
&lt;p&gt;The domain separator prevents collision of otherwise identical structures. It is possible that two DApps come up with an identical structure like &lt;code&gt;Transfer(address from,address to,uint256 amount)&lt;&#x2F;code&gt; that should not be compatible. By introducing a domain separator the DApp developers are guaranteed that there can be no signature collision.&lt;&#x2F;p&gt;
&lt;p&gt;The domain separator also allows for multiple distinct signatures use-cases on the same struct instance within a given DApp. In the previous example, perhaps signatures from both &lt;code&gt;from&lt;&#x2F;code&gt; and &lt;code&gt;to&lt;&#x2F;code&gt; are required. By providing two distinct domain separators these signatures can be distinguished from each other.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 1&lt;&#x2F;strong&gt;: Use the target contract address as domain separator. This solves the first problem, contracts coming up with identical types, but does not address the second use-case. The standard does suggest implementors to use the target contract address where this is appropriate.&lt;&#x2F;p&gt;
&lt;p&gt;The function &lt;code&gt;hashStruct&lt;&#x2F;code&gt; starts with a &lt;code&gt;typeHash&lt;&#x2F;code&gt; to separate types. By giving different types a different prefix the &lt;code&gt;encodeData&lt;&#x2F;code&gt; function only has to be injective within a given type. It is okay for &lt;code&gt;encodeData(a)&lt;&#x2F;code&gt; to equal &lt;code&gt;encodeData(b)&lt;&#x2F;code&gt; as long as &lt;code&gt;typeOf(a)&lt;&#x2F;code&gt; is not &lt;code&gt;typeOf(b)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale-for-typehash&quot;&gt;Rationale for &lt;code&gt;typeHash&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;typeHash&lt;&#x2F;code&gt; is designed to turn into a compile time constant in Solidity. For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; MAIL_TYPEHASH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 class=&quot;z-string&quot;&gt;  &amp;quot;Mail(address from,address to,string contents)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&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 the type hash several alternatives were considered and rejected for the reasons:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 2&lt;&#x2F;strong&gt;: Use ABIv2 function signatures. &lt;code&gt;bytes4&lt;&#x2F;code&gt; is not enough to be collision resistant. Unlike function signatures, there is negligible runtime cost incurred by using longer hashes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 3&lt;&#x2F;strong&gt;: ABIv2 function signatures modified to be 256-bit. While this captures type info, it does not capture any of the semantics other than the function. This is already causing a practical collision between &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt;&#x27;s and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;721&#x2F;&quot;&gt;ERC-721&lt;&#x2F;a&gt;&#x27;s &lt;code&gt;transfer(address,uint256)&lt;&#x2F;code&gt;, where in the former the &lt;code&gt;uint256&lt;&#x2F;code&gt; refers to an amount and the latter to a unique id. In general ABIv2 favors compatibility where a hashing standard should prefer incompatibility.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 4&lt;&#x2F;strong&gt;: 256-bit ABIv2 signatures extended with parameter names and struct names. The &lt;code&gt;Mail&lt;&#x2F;code&gt; example from above would be encoded as &lt;code&gt;Mail(Person(string name,address wallet) from,Person(string name,address wallet) to,string contents)&lt;&#x2F;code&gt;. This is longer than the proposed solution. And indeed, the length of the string can grow exponentially in the length of the input (consider &lt;code&gt;struct A{B a;B b;}; struct B {C a;C b;}; …&lt;&#x2F;code&gt;). It also does not allow a recursive struct type (consider &lt;code&gt;struct List {uint256 value; List next;}&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 5&lt;&#x2F;strong&gt;: Include natspec documentation. This would include even more semantic information in the schemaHash and further reduces chances of collision. It makes extending and amending documentation a breaking changes, which contradicts common assumptions. It also makes the schemaHash mechanism very verbose.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale-for-encodedata&quot;&gt;Rationale for &lt;code&gt;encodeData&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;encodeData&lt;&#x2F;code&gt; is designed to allow easy implementation of &lt;code&gt;hashStruct&lt;&#x2F;code&gt; in Solidity:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashStruct&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Mail&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        MAIL_TYPEHASH&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mail&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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&gt;        mail&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contents&lt;&#x2F;span&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;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;it also allows for an efficient in-place implementation in EVM&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; hashStruct&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;Mail&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; mail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compute sub-hashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; typeHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; MAIL_TYPEHASH&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; contentsHash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contents&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Back up select memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; temp1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; temp2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Write typeHash and sub-hashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; typeHash&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; contentsHash&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compute hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 128&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Restore memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; temp1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;        mstore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mail&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; temp2&lt;&#x2F;span&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;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 in-place implementation makes strong but reasonable assumptions on the memory layout of structs in memory. Specifically it assumes structs are not allocated below address 32, that members are stored in order, that all values are padded to 32-byte boundaries, and that dynamic and reference types are stored as a 32-byte pointers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 6&lt;&#x2F;strong&gt;: Tight packing. This is the default behaviour in Solidity when calling &lt;code&gt;keccak256&lt;&#x2F;code&gt; with multiple arguments. It minimizes the number of bytes to be hashed but requires complicated packing instructions in EVM to do so. It does not allow in-place computation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 7&lt;&#x2F;strong&gt;: ABIv2 encoding. Especially with the upcoming &lt;code&gt;abi.encode&lt;&#x2F;code&gt; it should be easy to use &lt;code&gt;abi.encode&lt;&#x2F;code&gt; as the &lt;code&gt;encodeData&lt;&#x2F;code&gt; function. The ABIv2 standard by itself fails the determinism security criteria. There are several valid ABIv2 encodings of the same data. ABIv2 does not allow in-place computation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 8&lt;&#x2F;strong&gt;: Leave &lt;code&gt;typeHash&lt;&#x2F;code&gt; out of &lt;code&gt;hashStruct&lt;&#x2F;code&gt; and instead combine it with the domain separator. This is more efficient, but then the semantics of the Solidity &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash function are not injective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative 9&lt;&#x2F;strong&gt;: Support cyclical data structures. The current standard is optimized for tree-like data structures and undefined for cyclical data structures. To support cyclical data a stack containing the path to the current node needs to be maintained and a stack offset substituted when a cycle is detected. This is prohibitively more complex to specify and implement. It also breaks composability where the hashes of the member values are used to construct the hash of the struct (the hash of the member values would depend on the path). It is possible to extend the standard in a compatible way to define hashes of cyclical data.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, a straightforward implementation is sub-optimal for directed acyclic graphs. A simple recursion through the members can visit the same node twice. Memoization can optimize this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale-for-domainseparator&quot;&gt;Rationale for &lt;code&gt;domainSeparator&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Since different domains have different needs, an extensible scheme is used where the DApp specifies a &lt;code&gt;EIP712Domain&lt;&#x2F;code&gt; struct type and an instance &lt;code&gt;eip712Domain&lt;&#x2F;code&gt; which it passes to the user-agent. The user-agent can then apply different verification measures depending on the fields that are there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The RPC calls, web3 methods and &lt;code&gt;SomeStruct.typeHash&lt;&#x2F;code&gt; parameter are currently undefined. Defining them should not affect the behaviour of existing DApps.&lt;&#x2F;p&gt;
&lt;p&gt;The Solidity expression &lt;code&gt;keccak256(someInstance)&lt;&#x2F;code&gt; for an instance &lt;code&gt;someInstance&lt;&#x2F;code&gt; of a struct type &lt;code&gt;SomeStruct&lt;&#x2F;code&gt; is valid syntax. It currently evaluates to the &lt;code&gt;keccak256&lt;&#x2F;code&gt; hash of the memory address of the instance. This behaviour should be considered dangerous. In some scenarios it will appear to work correctly but in others it will fail determinism and&#x2F;or injectiveness. DApps that depend on the current behaviour should be considered dangerously broken.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;An example contract can be found in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;.&#x2F;assets&#x2F;Example.sol&quot;&gt;Example.sol&lt;&#x2F;a&gt; and an example implementation of signing in JavaScript in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;.&#x2F;assets&#x2F;Example.js&quot;&gt;Example.js&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;replay-attacks&quot;&gt;Replay attacks&lt;&#x2F;h3&gt;
&lt;p&gt;This standard is only about signing messages and verifying signatures. In many practical applications, signed messages are used to authorize an action, for example an exchange of tokens. It is &lt;em&gt;very important&lt;&#x2F;em&gt; that implementers make sure the application behaves correctly when it sees the same signed message twice. For example, the repeated message should be rejected or the authorized action should be idempotent. How this is implemented is specific to the application and out of scope for this standard.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;frontrunning-attacks&quot;&gt;Frontrunning attacks&lt;&#x2F;h3&gt;
&lt;p&gt;The mechanism for reliably broadcasting a signature is application-specific and out of scope for this standard. When the signature is broadcast to a blockchain for use in a contract, the application has to be secure against frontrunning attacks. In this kind of attack, an attacker intercepts the signature and submits it to the contract before the original intended use takes place. The application should behave correctly when the signature is submitted first by an attacker, for example by rejecting it or simply producing exactly the same effect as intended by the signer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>DEVp2p snappy compression</title>
        <published>2017-09-07T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Péter Szilágyi</name><email>peter@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/706/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/706/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:706"
            label="EIP-706" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/706/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The base networking protocol (DEVp2p) used by Ethereum currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync as well as normal operation slower and laggier.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP proposes a tiny extension to the DEVp2p protocol to enable &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Snappy_(compression)&quot;&gt;Snappy compression&lt;&#x2F;a&gt; on all message payloads after the initial handshake. After extensive benchmarks, results show that data traffic is decreased by 60-80% for initial sync. You can find exact numbers below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Synchronizing the Ethereum main network (block 4,248,000) in Geth using fast sync currently consumes 1.01GB upload and 33.59GB download bandwidth. On the Rinkeby test network (block 852,000) it&#x27;s 55.89MB upload and 2.51GB download.&lt;&#x2F;p&gt;
&lt;p&gt;However, most of this data (blocks, transactions) are heavily compressible. By enabling compression at the message payload level, we can reduce the previous numbers to 1.01GB upload &#x2F; 13.46GB download on the main network, and 46.21MB upload &#x2F; 463.65MB download on the test network.&lt;&#x2F;p&gt;
&lt;p&gt;The motivation behind doing this at the DEVp2p level (opposed to eth for example) is that it would enable compression for all sub-protocols (eth, les, bzz) seamlessly, reducing any complexity those protocols might incur in trying to individually optimize for data traffic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Bump the advertised DEVp2p version number from &lt;code&gt;4&lt;&#x2F;code&gt; to &lt;code&gt;5&lt;&#x2F;code&gt;. If during handshake, the remote side advertises support only for version &lt;code&gt;4&lt;&#x2F;code&gt;, run the exact same protocol as until now.&lt;&#x2F;p&gt;
&lt;p&gt;If the remote side advertises a DEVp2p version &lt;code&gt;&amp;gt;= 5&lt;&#x2F;code&gt;, inject a Snappy compression step right before encrypting the DEVp2p message during sending:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A message consists of &lt;code&gt;{Code, Size, Payload}&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Compress the original payload with Snappy and store it in the same field.&lt;&#x2F;li&gt;
&lt;li&gt;Update the message size to the length of the compressed payload.&lt;&#x2F;li&gt;
&lt;li&gt;Encrypt and send the message as before, oblivious to compression.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Similarly to message sending, when receiving a DEVp2p v5 message from a remote node, insert a Snappy decompression step right after decrypting the DEVp2p message:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A message consists of &lt;code&gt;{Code, Size, Payload}&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Decrypt the message payload as before, oblivious to compression.&lt;&#x2F;li&gt;
&lt;li&gt;Decompress the payload with Snappy and store it in the same field.&lt;&#x2F;li&gt;
&lt;li&gt;Update the message size to the length of the decompressed payload.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Important caveats:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The handshake message is &lt;strong&gt;never&lt;&#x2F;strong&gt; compressed, since it is needed to negotiate the common version.&lt;&#x2F;li&gt;
&lt;li&gt;Snappy framing is &lt;strong&gt;not&lt;&#x2F;strong&gt; used, since the DEVp2p protocol already message oriented.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note: Snappy supports uncompressed binary literals (up to 4GB) too, leaving room for fine-tuned future optimisations for already compressed or encrypted data that would have no gain of compression (Snappy usually detects this case automatically).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;avoiding-dos-attacks&quot;&gt;Avoiding DOS attacks&lt;&#x2F;h3&gt;
&lt;p&gt;Currently a DEVp2p message length is limited to 24 bits, amounting to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blindly decompress messages, since they may get significantly larger than 16MB.&lt;&#x2F;p&gt;
&lt;p&gt;However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory (&lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;snappy&#x2F;blob&#x2F;master&#x2F;format_description.txt#L20&quot;&gt;the stream starts with the uncompressed length up to a maximum of &lt;code&gt;2^32 - 1&lt;&#x2F;code&gt; stored as a little-endian varint&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;). This can be used to discard any messages which decompress above some threshold. &lt;strong&gt;The proposal is to use the same limit (16MB) as the threshold for decompressed messages.&lt;&#x2F;strong&gt; This retains the same guarantees that the current DEVp2p protocol does, so there won&#x27;t be surprises in application level protocols.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alternatives-discarded&quot;&gt;Alternatives (discarded)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Alternative solutions to data compression that have been brought up and discarded are:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Extend protocol &lt;code&gt;xyz&lt;&#x2F;code&gt; to support compressed messages versus doing it at DEVp2p level:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro&lt;&#x2F;strong&gt;: Can be better optimized when to compress and when not to.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Mixes in transport layer encoding into application layer logic.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Makes the individual message specs more convoluted with compression details.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Requires cross client coordination on every single protocol, making the effort much harder and repeated (eth, les, shh, bzz).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Introduce seamless variations of protocol such as &lt;code&gt;xyz&lt;&#x2F;code&gt; expanded with &lt;code&gt;xyz-compressed&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro&lt;&#x2F;strong&gt;: Can be done (hacked in) without cross client coordination.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Litters the network with client specific protocol announces.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Needs to be specced in an EIP for cross interoperability anyway.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Other ideas that have been discussed and discarded:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t explicitly limit the decompressed message size, only the compressed one:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro&lt;&#x2F;strong&gt;: Allows larger messages to traverse through DEVp2p.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Upper layer protocols need to check and discard large messages.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Con&lt;&#x2F;strong&gt;: Needs lazy decompression to allow size limitations without DOS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal is fully backward compatible. Clients upgrading to the proposed DEVp2p protocol version &lt;code&gt;5&lt;&#x2F;code&gt; should still support skipping the compression step for connections that only advertise version &lt;code&gt;4&lt;&#x2F;code&gt; of the DEVp2p protocol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;You can find a reference implementation of this EIP in https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;15106.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-vectors&quot;&gt;Test vectors&lt;&#x2F;h2&gt;
&lt;p&gt;There is more than one valid encoding of any given input, and there is more than one good internal compression algorithm within Snappy when trading off throughput for output size. As such, different implementations might produce slight variations in the compressed form, but all should be cross compatible between each other.&lt;&#x2F;p&gt;
&lt;p&gt;As an example, take hex encoded RLP of block #272621 from the Rinkeby test network: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.githubusercontent.com&#x2F;karalabe&#x2F;72a1a6c4c1dbe6d4996879e415697f06&#x2F;raw&#x2F;195bf0c0050ee9805fcd5db4b5b650c58879a55f&#x2F;block.rlp&quot;&gt;block.rlp (~3MB)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Encoding the raw RLP via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;snappy&quot;&gt;Go&#x27;s Snappy library&lt;&#x2F;a&gt; yields: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.githubusercontent.com&#x2F;karalabe&#x2F;72a1a6c4c1dbe6d4996879e415697f06&#x2F;raw&#x2F;195bf0c0050ee9805fcd5db4b5b650c58879a55f&#x2F;block.go.snappy&quot;&gt;block.go.snappy (~70KB)&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Encoding the raw RLP via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;andrix&#x2F;python-snappy&quot;&gt;Python&#x27;s Snappy library&lt;&#x2F;a&gt; yields: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.githubusercontent.com&#x2F;karalabe&#x2F;72a1a6c4c1dbe6d4996879e415697f06&#x2F;raw&#x2F;195bf0c0050ee9805fcd5db4b5b650c58879a55f&#x2F;block.py.snappy&quot;&gt;block.py.snappy (~70KB)&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You can verify that an encoded binary can be decoded into the proper plaintext using the following snippets:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;go&quot;&gt;Go&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; get&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;package&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; main&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 class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encoding&#x2F;hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;fmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;io&#x2F;ioutil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;log&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;os&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;github.com&#x2F;golang&#x2F;snappy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read and decode the decompressed file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	plainhex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ioutil&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ReadFile&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;os&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Args&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Failed to read decompressed file &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; os&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Args&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	plain&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; hex&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;DecodeString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;plainhex&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Failed to decode decompressed file: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read and decode the compressed file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	comphex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ioutil&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ReadFile&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;os&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Args&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Failed to read compressed file &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; os&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;Args&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	comp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; hex&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;DecodeString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;comphex&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Failed to decode compressed file: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make sure they match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	decomp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; snappy&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;nil&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; comp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Failed to decompress compressed file: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; err&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Equal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;plain&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; decomp&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;		fmt&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Booo, decompressed file does not match provided plain text!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-keyword&quot;&gt;		return&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 class=&quot;z-variable z-other&quot;&gt;	fmt&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Yay, decompressed data matched provided plain text!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.go.snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Yay,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; decompressed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; matched&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; text!&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 class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.py.snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Yay,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; decompressed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; matched&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; text!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;python&quot;&gt;Python&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pip&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; python-snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sys&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read and decode the decompressed file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;with&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;argv&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; file&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plainhex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; file&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; plainhex&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Read and decode the compressed file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;with&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;sys&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;argv&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; file&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    comphex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; file&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;comp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; comphex&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make sure they match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;decomp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; snappy&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;uncompress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;comp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; decomp&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Booo, decompressed file does not match provided plain text!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-support&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Yay, decompressed data matched provided plain text!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; python&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.py&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.go.snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Yay,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; decompressed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; matched&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; text!&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 class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; python&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.py&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.rlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; block.py.snappy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Yay,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; decompressed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; matched&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; provided&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; plain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; text!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Snappy website: https:&#x2F;&#x2F;google.github.io&#x2F;snappy&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;Snappy specification: https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;snappy&#x2F;blob&#x2F;master&#x2F;format_description.txt&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Create `eth_chainId` method for JSON-RPC</title>
        <published>2017-08-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Isaac Ardis</name><email>isaac.ardis@gmail.com</email>
	</author>
	
	<author>
		<name>Wei Tang</name><uri>https://github.com/sorpaas</uri>
	</author>
	
	<author>
		<name>Fan Torchz</name><uri>https://github.com/tcz001</uri>
	</author>
	
	<author>
		<name>Erik Marks</name><uri>https://github.com/rekmarks</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/695/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-695-create-eth-chainid-method-for-json-rpc/1845" />
        

        <id>https://wg-eips.ritovision.com/695/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:695"
            label="EIP-695" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/695/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Include &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; method in &lt;code&gt;eth_&lt;&#x2F;code&gt;-namespaced JSON-RPC methods.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; method should return a single STRING result
for an integer value in hexadecimal format, describing the
currently configured &lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt; value used for signing replay-protected transactions,
introduced by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently although we can use &lt;code&gt;net_version&lt;&#x2F;code&gt; RPC call to get the
current network ID, there&#x27;s no RPC for querying the chain ID. This
makes it impossible to determine the current actual blockchain using
the RPC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;eth-chainid&quot;&gt;&lt;code&gt;eth_chainId&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Returns the currently configured chain ID, a value used in replay-protected transaction
signing as introduced by &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The chain ID returned should always correspond to the information in the current known
head block. This ensures that caller of this RPC method can always use the retrieved
information to sign transactions built on top of the head.&lt;&#x2F;p&gt;
&lt;p&gt;If the current known head block does not specify a chain ID, the client should treat any
calls to &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; as though the method were not supported, and return a suitable
error.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h4&gt;
&lt;p&gt;None.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;returns&quot;&gt;Returns&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;QUANTITY&lt;&#x2F;code&gt; - integer of the current chain ID.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; --&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{&amp;quot;jsonrpc&amp;quot;:&amp;quot;2.0&amp;quot;,&amp;quot;method&amp;quot;:&amp;quot;eth_chainId&amp;quot;,&amp;quot;params&amp;quot;:[],&amp;quot;id&amp;quot;:83}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Result&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;83&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;jsonrpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x3d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 61&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;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;An ETH&#x2F;ETC client can accidentally connect to an ETC&#x2F;ETH RPC
endpoint without knowing it unless it tries to sign a transaction or
it fetches a transaction that is known to have signed with a chain
ID. This has since caused trouble for application developers, such as
MetaMask, to add multi-chain support.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Not relevant.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Consumers should prefer &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; over &lt;code&gt;net_version&lt;&#x2F;code&gt;, so that they can reliably identify chain they are communicating with.&lt;&#x2F;p&gt;
&lt;p&gt;Implementers should take care to implement &lt;code&gt;eth_chainId&lt;&#x2F;code&gt; correctly and promote its use, since the chain ID is critical in replay attack prevention as described in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt;, and consumers will rely on it to identify the chain they are communicating with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity&#x2F;pull&#x2F;6329&quot;&gt;Parity PR&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;17617&quot;&gt;Geth PR&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereumproject&#x2F;go-ethereum&#x2F;pull&#x2F;336&quot;&gt;Geth Classic PR&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;&#x2F;h2&gt;
&lt;p&gt;Return value &lt;code&gt;QUANTITY&lt;&#x2F;code&gt; adheres to standard JSON RPC hex value encoding, as documented in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum.org&#x2F;en&#x2F;developers&#x2F;docs&#x2F;apis&#x2F;json-rpc&#x2F;#hex-encoding&quot;&gt;Ethereum.org documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>URL Format for Transaction Requests</title>
        <published>2017-08-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Daniel A. Nagy</name><uri>https://github.com/nagydani</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/681/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-681-representing-various-transactions-as-urls" />
        

        <id>https://wg-eips.ritovision.com/681/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:681"
            label="ERC-681" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/681/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard way of representing various transactions, especially payment requests in ether and &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens as URLs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user&#x27;s preferred wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be confirmed by the (authenticated) user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs could be delivered through a very broad, ever growing selection of channels.&lt;&#x2F;p&gt;
&lt;p&gt;This specification supersedes the defunct ERC-67, which is a URL format for representing arbitrary transactions in a low-level fashion. This ERC focuses specifically on the important special case of payment requests, while allowing for other, ABI-specified transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;syntax&quot;&gt;Syntax&lt;&#x2F;h3&gt;
&lt;p&gt;Payment request URLs contain &quot;ethereum&quot; in their schema (protocol) part and are constructed as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request                 = schema_prefix target_address [ &amp;quot;@&amp;quot; chain_id ] [ &amp;quot;&#x2F;&amp;quot; function_name ] [ &amp;quot;?&amp;quot; parameters ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;schema_prefix           = &amp;quot;ethereum&amp;quot; &amp;quot;:&amp;quot; [ &amp;quot;pay-&amp;quot; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;target_address          = ethereum_address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chain_id                = 1*DIGIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function_name           = STRING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ethereum_address        = ( &amp;quot;0x&amp;quot; 40*HEXDIG ) &#x2F; ENS_NAME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parameters              = parameter *( &amp;quot;&amp;amp;&amp;quot; parameter )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parameter               = key &amp;quot;=&amp;quot; value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key                     = &amp;quot;value&amp;quot; &#x2F; &amp;quot;gas&amp;quot; &#x2F; &amp;quot;gasLimit&amp;quot; &#x2F; &amp;quot;gasPrice&amp;quot; &#x2F; TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;value                   = number &#x2F; ethereum_address &#x2F; STRING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number                  = [ &amp;quot;-&amp;quot; &#x2F; &amp;quot;+&amp;quot; ] *DIGIT [ &amp;quot;.&amp;quot; 1*DIGIT ] [ ( &amp;quot;e&amp;quot; &#x2F; &amp;quot;E&amp;quot; ) [ 1*DIGIT ] ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;TYPE&lt;&#x2F;code&gt; is a standard ABI type name, as defined in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;en&#x2F;develop&#x2F;abi-spec.html&quot;&gt;Ethereum Contract ABI specification&lt;&#x2F;a&gt;. &lt;code&gt;STRING&lt;&#x2F;code&gt; is a URL-encoded unicode string of arbitrary length, where delimiters and the
percentage symbol (&lt;code&gt;%&lt;&#x2F;code&gt;) are mandatorily hex-encoded with a &lt;code&gt;%&lt;&#x2F;code&gt; prefix.&lt;&#x2F;p&gt;
&lt;p&gt;Note that a &lt;code&gt;number&lt;&#x2F;code&gt; can be expressed in &lt;em&gt;scientific notation&lt;&#x2F;em&gt;, with a multiplier of a power of 10. Only integer numbers are allowed, so the exponent MUST be greater or equal to the number of decimals after the point.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;em&gt;key&lt;&#x2F;em&gt; in the parameter list is &lt;code&gt;value&lt;&#x2F;code&gt;, &lt;code&gt;gasLimit&lt;&#x2F;code&gt;, &lt;code&gt;gasPrice&lt;&#x2F;code&gt; or &lt;code&gt;gas&lt;&#x2F;code&gt; then &lt;em&gt;value&lt;&#x2F;em&gt; MUST be a &lt;code&gt;number&lt;&#x2F;code&gt;. Otherwise, it must correspond to the &lt;code&gt;TYPE&lt;&#x2F;code&gt; string used as &lt;em&gt;key&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For the syntax of ENS_NAME, please consult &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;ERC-137&lt;&#x2F;a&gt; defining Ethereum Name Service.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;semantics&quot;&gt;Semantics&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;target_address&lt;&#x2F;code&gt; is mandatory and denotes either the beneficiary of native token payment (see below) or the contract address with which the user is asked to interact.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;chain_id&lt;&#x2F;code&gt; is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no &lt;code&gt;chain_id&lt;&#x2F;code&gt; is present, the client&#x27;s current network setting remains effective.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;function_name&lt;&#x2F;code&gt; is missing, then the URL is requesting payment in the native token of the blockchain, which is ether in our case. The amount is specified in &lt;code&gt;value&lt;&#x2F;code&gt; parameter, in the atomic unit (i.e. wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address &lt;code&gt;0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359&lt;&#x2F;code&gt; would look as follows:
&lt;a href=&quot;ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18&quot;&gt;ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Requesting payments in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens involves a request to call the &lt;code&gt;transfer&lt;&#x2F;code&gt; function of the token contract with an &lt;code&gt;address&lt;&#x2F;code&gt; and a &lt;code&gt;uint256&lt;&#x2F;code&gt; typed parameter, containing the &lt;em&gt;beneficiary address&lt;&#x2F;em&gt; and the &lt;em&gt;amount in atomic units&lt;&#x2F;em&gt;, respectively. For example,
requesting a Unicorn to address &lt;code&gt;0x8e23ee67d1332ad560396262c48ffbb01f93d052&lt;&#x2F;code&gt; looks as follows:
&lt;a href=&quot;ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7&#x2F;transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&amp;amp;uint256=1&quot;&gt;ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7&#x2F;transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&amp;amp;uint256=1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name consisting of &lt;code&gt;0x&lt;&#x2F;code&gt; followed by 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the indicated amount is only a suggestion (as are all the supplied arguments) which the user is free to change. With no indicated amount, the user should be prompted to enter the amount to be paid.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly &lt;code&gt;gasLimit&lt;&#x2F;code&gt; and &lt;code&gt;gasPrice&lt;&#x2F;code&gt; are suggested user-editable values for &lt;em&gt;gas limit&lt;&#x2F;em&gt; and &lt;em&gt;gas price&lt;&#x2F;em&gt;, respectively, for the requested transaction. It is acceptable to abbreviate &lt;code&gt;gasLimit&lt;&#x2F;code&gt; as &lt;code&gt;gas&lt;&#x2F;code&gt;, the two are treated synonymously.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The proposed format is chosen to resemble &lt;code&gt;bitcoin:&lt;&#x2F;code&gt; URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is facilitated by the exponent so that amount values can be expressed in their nominal units, just like in the case of &lt;code&gt;bitcoin:&lt;&#x2F;code&gt;. The use of scientific notation is strongly encouraged when expressing monetary value in ether or &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens. For better human readability, the exponent should be the decimal value of the nominal unit: 18 for ether or the value returned by &lt;code&gt;decimals()&lt;&#x2F;code&gt; of the token contract for &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; tokens. Additional parameters may be added, if popular use cases requiring them emerge in practice.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;0x&lt;&#x2F;code&gt; prefix before ethereum addresses specified as hexadecimal numbers is following established practice and also unambiguously distinguishes hexadecimal addresses from ENS names consisting of 40 alphanumeric characters.&lt;&#x2F;p&gt;
&lt;p&gt;Future upgrades that are partially or fully incompatible with this proposal must use a prefix other than &lt;code&gt;pay-&lt;&#x2F;code&gt; that is separated by a dash (&lt;code&gt;-&lt;&#x2F;code&gt;) character from whatever follows it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;In the fairly common case of only indicating the recipient address in a request for payment in ether, this specification is compatible with the superseded ERC-67.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;Since irreversible transactions can be initiated with parameters from such URLs, the integrity and authenticity of these URLs are of great importance.
In particular, changing either the recipient address or the amount transferred can be a profitable attack. Users should only use URLs received from authenticated sources with adequate integrity protection.&lt;&#x2F;p&gt;
&lt;p&gt;To prevent malicious redirection of payments using ENS, hexadecimal interpretation of Ethereum addresses must have precedence over ENS lookups. Client software may alert the user if an ENS address is visually similar to a hexadecimal address or even outright reject such addresses as likely phishing attacks.&lt;&#x2F;p&gt;
&lt;p&gt;In order to make sure that the amount transacted is the same as the amount intended, the amount communicated to the human user should be easily verifiable by inspection, including the order of magnitude. In case of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; token payments, if the payer client has access to the blockchain or some other trusted source of information about the token contract, the interface should display the amount in the units specified in the token contract. Otherwise, it should be displayed as expressed in the URL, possibly alerting the user to the uncertainty of the nominal unit. To facilitate human inspection of the amount, the use of scientific notation with an exponent corresponding to the nominal unit of the transacted token (e.g. 18 in case of ether) is advisable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Embedding transaction status code in receipts</title>
        <published>2017-06-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><email>nick@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/658/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/658/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:658"
            label="EIP-658" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/658/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP replaces the intermediate state root field of the receipt with a status code indicating if the top-level call succeeded or failed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;With the introduction of the REVERT opcode in EIP140, it is no longer possible for users to assume that a transaction failed iff it consumed all gas. As a result, there is no clear mechanism for callers to determine whether a transaction succeeded and the state changes contained in it were applied.&lt;&#x2F;p&gt;
&lt;p&gt;Full nodes can provide RPCs to get a transaction return status and value by replaying the transaction, but fast nodes can only do this for nodes after their pivot point, and light nodes cannot do this at all, making a non-consensus solution impractical.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with the return status (1 for success, 0 for failure). This both allows callers to determine success status, and remedies the previous omission of return data from the receipt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;For blocks where block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM, the intermediate state root is replaced by a status code, 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This constitutes a minimal possible change that permits fetching the success&#x2F;failure state of transactions, preserving existing capabilities with minimum disruption or additional work for Metropolis.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Metropolis Difficulty Bomb Delay and Block Reward Reduction</title>
        <published>2017-06-21T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Afri Schoedon</name><uri>https://github.com/5chdn</uri>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/649/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/649" />
        

        <id>https://wg-eips.ritovision.com/649/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:649"
            label="EIP-649" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/649/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The average block times are increasing due to the difficulty bomb (also known as the &quot;&lt;em&gt;ice age&lt;&#x2F;em&gt;&quot;) slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork, the first part of the Metropolis fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Starting with &lt;code&gt;BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt; the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 3 ETH, uncle and nephew rewards will be adjusted accordingly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The Casper development and switch to proof-of-stake is delayed, the Ethash proof-of-work should be feasible for miners and allow sealing new blocks every 15 seconds on average for another one and a half years. With the delay of the ice age, there is a desire to not suddenly also increase miner rewards. The difficulty bomb has been known about for a long time and now it&#x27;s going to stop from happening. In order to maintain stability of the system, a block reward reduction that offsets the ice age delay would leave the system in the same general state as before. Reducing the reward also decreases the likelihood of a miner driven chain split as Ethereum approaches proof-of-stake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;relax-difficulty-with-fake-block-number&quot;&gt;Relax Difficulty with Fake Block Number&lt;&#x2F;h4&gt;
&lt;p&gt;For the purposes of &lt;code&gt;calc_difficulty&lt;&#x2F;code&gt;, simply replace the use of &lt;code&gt;block.number&lt;&#x2F;code&gt;, as used in the exponential ice age component, with the formula:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fake_block_number = max(0, block.number - 3_000_000) if block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM else block.number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;adjust-block-uncle-and-nephew-rewards&quot;&gt;Adjust Block, Uncle, and Nephew rewards&lt;&#x2F;h4&gt;
&lt;p&gt;To ensure a constant Ether issuance, adjust the block reward to &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;, where&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_block_reward = 3_000_000_000_000_000_000 if block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM else block.reward&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(3E18 wei, or 3,000,000,000,000,000,000 wei, or 3 ETH).&lt;&#x2F;p&gt;
&lt;p&gt;Analogue, if an uncle is included in a block for &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt; such that &lt;code&gt;block.number - uncle.number = k&lt;&#x2F;code&gt;, the uncle reward is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_uncle_reward = (8 - k) * new_block_reward &#x2F; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the existing pre-Metropolis formula for uncle rewards, simply adjusted with &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The nephew reward for &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt; is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;new_nephew_reward = new_block_reward &#x2F; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the existing pre-Metropolis formula for nephew rewards, simply adjusted with &lt;code&gt;new_block_reward&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This will delay the ice age by 42 million seconds (approximately 1.4 years), so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively &lt;em&gt;pause&lt;&#x2F;em&gt; the difficulty between different blocks. This would lead to similar results.&lt;&#x2F;p&gt;
&lt;p&gt;This was previously discussed at All Core Devs Meeting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%209.md#metropolis-timing-and-roadmap-discussion&quot;&gt;#09&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2012.md#5-metropolis-update&quot;&gt;#12&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson&quot;&gt;#13&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs&quot;&gt;#14&lt;&#x2F;a&gt;. Consensus on the specification was achieved in All Core Devs Meeting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2019.md&quot;&gt;#19&lt;&#x2F;a&gt; and specification drafted in EIP issue &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;649&quot;&gt;#649&lt;&#x2F;a&gt;. It was decided to replace EIP &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;186&quot;&gt;#186&lt;&#x2F;a&gt; and include the block reward reduction along with the difficulty bomb delay in All Core Devs Meeting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2020.md&quot;&gt;#20&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2021.md&quot;&gt;#21&lt;&#x2F;a&gt;; accepted in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pm&#x2F;blob&#x2F;master&#x2F;AllCoreDevs-EL-Meetings&#x2F;Meeting%2022.md&quot;&gt;#22&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It&#x27;s suggested to include this EIP in the first of the two Metropolis hard-forks, the &lt;em&gt;Byzantium&lt;&#x2F;em&gt; fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Test cases exist in ethereum&#x2F;tests &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;pull&#x2F;269&quot;&gt;#269&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The following clients implemented EIP-649:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Geth &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;15028&quot;&gt;#15028&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Parity &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity&#x2F;pull&#x2F;5855&quot;&gt;#5855&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;EthereumJ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;ethereumj&#x2F;pull&#x2F;927&quot;&gt;#927&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Cpp-Ethereum &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;cpp-ethereum&#x2F;issues&#x2F;4050&quot;&gt;#4050&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;PyEthereum &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;pull&#x2F;383&quot;&gt;#383&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Yellow Paper implements EIP-649 in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;yellowpaper&#x2F;pull&#x2F;333&quot;&gt;#333&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Other notable implementations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Eth-Isabelle &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pirapira&#x2F;eth-isabelle&#x2F;issues&#x2F;459&quot;&gt;#459&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Py-EVM &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;py-evm&#x2F;pull&#x2F;123&quot;&gt;#123&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Whisper Specification</title>
        <published>2017-05-05T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vlad Gluhovsky</name><email>gluk256@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/627/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/627/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        

        
        <category
            term="tag:eip:627"
            label="EIP-627" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/627/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP describes the format of Whisper messages within the ÐΞVp2p Wire Protocol.
This EIP should substitute the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Whisper-Wire-Protocol&quot;&gt;existing specification&lt;&#x2F;a&gt;.
More detailed documentation on Whisper could be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;wiki&#x2F;Whisper&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;It is necessary to specify the standard for Whisper messages in order to ensure forward compatibility of different Whisper clients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;All Whisper messages sent as ÐΞVp2p Wire Protocol packets should be RLP-encoded arrays of data containing two objects: integer packet code followed by another object (whose type depends on the packet code).&lt;&#x2F;p&gt;
&lt;p&gt;If Whisper node does not support a particular packet code, it should just ignore the packet without generating any error.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;packet-codes&quot;&gt;Packet Codes&lt;&#x2F;h3&gt;
&lt;p&gt;The message codes reserved for Whisper protocol: 0 - 127.
Messages with unknown codes must be ignored, for forward compatibility of future versions.&lt;&#x2F;p&gt;
&lt;p&gt;The Whisper sub-protocol should support the following packet codes:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;EIP&lt;&#x2F;th&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Int Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Status&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Messages&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;PoW Requirement&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Bloom Filter&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;-------&lt;&#x2F;td&gt;&lt;td&gt;----------------------------&lt;&#x2F;td&gt;&lt;td&gt;-----------&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The following message codes are optional, but they are reserved for specific purpose.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;EIP&lt;&#x2F;th&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Int Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;P2P Request&lt;&#x2F;td&gt;&lt;td&gt;126&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;P2P Message&lt;&#x2F;td&gt;&lt;td&gt;127&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;-------&lt;&#x2F;td&gt;&lt;td&gt;----------------------------&lt;&#x2F;td&gt;&lt;td&gt;-----------&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;packet-format-and-usage&quot;&gt;Packet Format and Usage&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Status&lt;&#x2F;strong&gt; [&lt;code&gt;0&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x00) followed by a list of values: integer version, float PoW requirement, and bloom filter, in this order. The bloom filter parameter is optional; if it is missing or nil, the node is considered to be full node (i.e. accepts all messages). The format of PoW and bloom filter please see below (message codes 2 and 3).&lt;&#x2F;p&gt;
&lt;p&gt;Status message should be sent after the initial handshake and prior to any other messages.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Messages&lt;&#x2F;strong&gt; [&lt;code&gt;1&lt;&#x2F;code&gt;, &lt;code&gt;whisper_envelopes&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x01) followed by a list (possibly empty) of Whisper Envelopes.&lt;&#x2F;p&gt;
&lt;p&gt;This packet is used for sending the standard Whisper envelopes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;PoW Requirement&lt;&#x2F;strong&gt; [&lt;code&gt;2&lt;&#x2F;code&gt;, &lt;code&gt;PoW&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x02) followed by a single floating point value of PoW. This value is the IEEE 754 binary representation of 64-bit floating point number. Values of qNAN, sNAN, INF and -INF are not allowed. Negative values are also not allowed.&lt;&#x2F;p&gt;
&lt;p&gt;This packet is used by Whisper nodes for dynamic adjustment of their individual PoW requirements. Recipient of this message should no longer deliver the sender messages with PoW lower than specified in this message.&lt;&#x2F;p&gt;
&lt;p&gt;PoW is defined as average number of iterations, required to find the current BestBit (the number of leading zero bits in the hash), divided by message size and TTL:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PoW = (2**BestBit) &#x2F; (size * TTL)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;PoW calculation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fn short_rlp(envelope) = rlp of envelope, excluding env_nonce field.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fn pow_hash(envelope, env_nonce) = sha3(short_rlp(envelope) ++ env_nonce)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fn pow(pow_hash, size, ttl) = 2**leading_zeros(pow_hash) &#x2F; (size * ttl)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where size is the size of the full RLP-encoded envelope.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Bloom Filter&lt;&#x2F;strong&gt; [&lt;code&gt;3&lt;&#x2F;code&gt;, &lt;code&gt;bytes&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x03) followed by a byte array of arbitrary size.&lt;&#x2F;p&gt;
&lt;p&gt;This packet is used by Whisper nodes for sharing their interest in messages with specific topics.&lt;&#x2F;p&gt;
&lt;p&gt;The Bloom filter is used to identify a number of topics to a peer without compromising (too much) privacy over precisely what topics are of interest. Precise control over the information content (and thus efficiency of the filter) may be maintained through the addition of bits.&lt;&#x2F;p&gt;
&lt;p&gt;Blooms are formed by the bitwise OR operation on a number of bloomed topics. The bloom function takes the topic and projects them onto a 512-bit slice. At most, three bits are marked for each bloomed topic.&lt;&#x2F;p&gt;
&lt;p&gt;The projection function is defined as a mapping from a 4-byte slice S to a 512-bit slice D; for ease of explanation, S will dereference to bytes, whereas D will dereference to bits.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LET D[*] = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FOREACH i IN { 0, 1, 2 } DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LET n = S[i]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IF S[3] &amp;amp; (2 ** i) THEN n += 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;D[n] = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;END FOR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;OPTIONAL&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;P2P Request&lt;&#x2F;strong&gt; [&lt;code&gt;126&lt;&#x2F;code&gt;, &lt;code&gt;whisper_envelope&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x7E) followed by a single Whisper Envelope.&lt;&#x2F;p&gt;
&lt;p&gt;This packet is used for sending Dapp-level peer-to-peer requests, e.g. Whisper Mail Client requesting old messages from the Whisper Mail Server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;P2P Message&lt;&#x2F;strong&gt; [&lt;code&gt;127&lt;&#x2F;code&gt;, &lt;code&gt;whisper_envelope&lt;&#x2F;code&gt;]&lt;&#x2F;p&gt;
&lt;p&gt;This packet contains two objects: integer message code (0x7F) followed by a single Whisper Envelope.&lt;&#x2F;p&gt;
&lt;p&gt;This packet is used for sending the peer-to-peer messages, which are not supposed to be forwarded any further. E.g. it might be used by the Whisper Mail Server for delivery of old (expired) messages, which is otherwise not allowed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;whisper-envelope&quot;&gt;Whisper Envelope&lt;&#x2F;h3&gt;
&lt;p&gt;Envelopes are RLP-encoded structures of the following format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[ Expiry, TTL, Topic, Data, Nonce ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Expiry&lt;&#x2F;code&gt;: 4 bytes (UNIX time in seconds).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;TTL&lt;&#x2F;code&gt;: 4 bytes (time-to-live in seconds).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Topic&lt;&#x2F;code&gt;: 4 bytes of arbitrary data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Data&lt;&#x2F;code&gt;: byte array of arbitrary size (contains encrypted message).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Nonce&lt;&#x2F;code&gt;: 8 bytes of arbitrary data (used for PoW calculation).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contents-of-data-field-of-the-message-optional&quot;&gt;Contents of Data Field of the Message (Optional)&lt;&#x2F;h3&gt;
&lt;p&gt;This section outlines the optional description of Data Field to set up an example. Later it may be moved to a separate EIP.&lt;&#x2F;p&gt;
&lt;p&gt;It is only relevant if you want to decrypt the incoming message, but if you only want to send a message, any other format would be perfectly valid and must be forwarded to the peers.&lt;&#x2F;p&gt;
&lt;p&gt;Data field contains encrypted message of the Envelope. In case of symmetric encryption, it also contains appended Salt (a.k.a. AES Nonce, 12 bytes). Plaintext (unencrypted) payload consists of the following concatenated fields: flags, auxiliary field, payload, padding and signature (in this sequence).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flags: 1 byte; first two bits contain the size of auxiliary field, third bit indicates whether the signature is present.&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;auxiliary field: up to 4 bytes; contains the size of payload.&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;payload: byte array of arbitrary size (may be zero).&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;padding: byte array of arbitrary size (may be zero).&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;signature: 65 bytes, if present.&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;salt: 12 bytes, if present (in case of symmetric encryption).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those unable to decrypt the message data are also unable to access the signature. The signature, if provided, is the ECDSA signature of the Keccak-256 hash of the unencrypted data using the secret key of the originator identity. The signature is serialised as the concatenation of the &lt;code&gt;R&lt;&#x2F;code&gt;, &lt;code&gt;S&lt;&#x2F;code&gt; and &lt;code&gt;V&lt;&#x2F;code&gt; parameters of the SECP-256k1 ECDSA signature, in that order. &lt;code&gt;R&lt;&#x2F;code&gt; and &lt;code&gt;S&lt;&#x2F;code&gt; are both big-endian encoded, fixed-width 256-bit unsigned. &lt;code&gt;V&lt;&#x2F;code&gt; is an 8-bit big-endian encoded, non-normalised and should be either 27 or 28.&lt;&#x2F;p&gt;
&lt;p&gt;The padding field was introduced in order to align the message size, since message size alone might reveal important metainformation. Padding can be arbitrary size. However, it is recommended that the size of Data Field (excluding the Salt) before encryption (i.e. plain text) should be factor of 256 bytes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;payload-encryption&quot;&gt;Payload Encryption&lt;&#x2F;h3&gt;
&lt;p&gt;Asymmetric encryption uses the standard Elliptic Curve Integrated Encryption Scheme with SECP-256k1 public key.&lt;&#x2F;p&gt;
&lt;p&gt;Symmetric encryption uses AES GCM algorithm with random 96-bit nonce.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Packet codes 0x00 and 0x01 are already used in all Whisper versions.&lt;&#x2F;p&gt;
&lt;p&gt;Packet code 0x02 will be necessary for the future development of Whisper. It will provide possibility to adjust the PoW requirement in real time. It is better to allow the network to govern itself, rather than hardcode any specific value for minimal PoW requirement.&lt;&#x2F;p&gt;
&lt;p&gt;Packet code 0x03 will be necessary for scalability of the network. In case of too much traffic, the nodes will be able to request and receive only the messages they are interested in.&lt;&#x2F;p&gt;
&lt;p&gt;Packet codes 0x7E and 0x7F may be used to implement Whisper Mail Server and Client. Without P2P messages it would be impossible to deliver the old messages, since they will be recognized as expired, and the peer will be disconnected for violating the Whisper protocol. They might be useful for other purposes when it is not possible to spend time on PoW, e.g. if a stock exchange will want to provide live feed about the latest trades.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP is compatible with Whisper version 6. Any client which does not implement certain packet codes should gracefully ignore the packets with those codes. This will ensure the forward compatibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The golang implementation of Whisper (v.6) already uses packet codes 0x00 - 0x03. Parity&#x27;s implementation of v.6 will also use codes 0x00 - 0x03. Codes 0x7E and 0x7F are reserved, but still unused and left for custom implementation of Whisper Mail Server.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Token with transaction handling model</title>
        <published>2017-05-03T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Dexaran</name><uri>https://github.com/Dexaran</uri><email>dexaran@ethereumclassic.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/223/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/erc-223-token-standard/12894" />
        

        <id>https://wg-eips.ritovision.com/223/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:223"
            label="ERC-223" />
        

        
        

        
        <summary type="html">Token with transaction handling model designed to behave identical to native currency (ether)</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/223/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following describes an interface and logic for fungible tokens that supports a &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; callback to notify contract recipients when tokens are received. This makes tokens behave identical to ether.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;This token introduces a communication model for contracts that can be utilized to straighten the behavior of contracts that interact with such tokens. Specifically, this proposal:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Informs receiving contracts of incoming token transfers, as opposed to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; where the recipient of a token transfer gets no notification.&lt;&#x2F;li&gt;
&lt;li&gt;Is more gas-efficient when depositing tokens to contracts.&lt;&#x2F;li&gt;
&lt;li&gt;Allows for &lt;code&gt;_data&lt;&#x2F;code&gt; recording for financial transfers.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Contracts intending to receive these tokens MUST implement &lt;code&gt;tokenReceived&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Token transfers to contracts not implementing &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; as described below MUST revert.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;token-contract&quot;&gt;Token contract&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;token-methods&quot;&gt;Token Methods&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;totalsupply&quot;&gt;&lt;code&gt;totalSupply&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Returns the total supply of the token. The functionality of this method is identical to that of ERC-20.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;name&quot;&gt;&lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;Returns the name of the token.  The functionality of this method is identical to that of ERC-20.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;symbol&quot;&gt;&lt;code&gt;symbol&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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;Returns the symbol of the token. The functionality of this method is identical to that of ERC-20.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;decimals&quot;&gt;&lt;code&gt;decimals&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decimals&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Returns the number of decimals of the token. The functionality of this method is identical to that of ERC-20.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;balanceof&quot;&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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;Returns the account balance of another account with address &lt;code&gt;_owner&lt;&#x2F;code&gt;. The functionality of this method is identical to that of ERC-20.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;transfer-address-uint&quot;&gt;&lt;code&gt;transfer(address, uint)&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 function must transfer tokens, and if &lt;code&gt;_to&lt;&#x2F;code&gt; is a contract, it must call the &lt;code&gt;tokenReceived(address, uint256, bytes calldata)&lt;&#x2F;code&gt; function of &lt;code&gt;_to&lt;&#x2F;code&gt;. If the &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function is not implemented in &lt;code&gt;_to&lt;&#x2F;code&gt; (recipient contract), then the transaction must fail and the transfer of tokens must be reverted.
If &lt;code&gt;_to&lt;&#x2F;code&gt; is an externally owned address, then the transaction must be sent without executing &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; in &lt;code&gt;_to&lt;&#x2F;code&gt;.
&lt;code&gt;_data&lt;&#x2F;code&gt; can be attached to this token transaction, but it requires more gas. &lt;code&gt;_data&lt;&#x2F;code&gt; can be empty.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function of &lt;code&gt;_to&lt;&#x2F;code&gt; MUST be called after all other operations to avoid re-entrancy attacks.&lt;&#x2F;p&gt;
&lt;p&gt;NOTE: If &lt;code&gt;transfer&lt;&#x2F;code&gt; function is &lt;code&gt;payable&lt;&#x2F;code&gt; and ether was deposited then the amount of deposited ether MUST be delivered to &lt;code&gt;_to&lt;&#x2F;code&gt; address alongside tokens. If ether was sent alongside tokens in this way then ether MUST be delivered first, then token balances must be updated, then &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function MUST be called in &lt;code&gt;_to&lt;&#x2F;code&gt; if it is a contract.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;transfer-address-uint-bytes&quot;&gt;&lt;code&gt;transfer(address, uint, bytes)&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 function must transfer tokens and invoke the function &lt;code&gt;tokenReceived (address, uint256, bytes)&lt;&#x2F;code&gt; in &lt;code&gt;_to&lt;&#x2F;code&gt;, if &lt;code&gt;_to&lt;&#x2F;code&gt; is a contract. If the &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function is not implemented in &lt;code&gt;_to&lt;&#x2F;code&gt; (recipient contract), then the transaction must fail and the transfer of tokens must not occur.
If &lt;code&gt;_to&lt;&#x2F;code&gt; is an externally owned address (determined by the code size being zero), then the transaction must be sent without executing &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; in &lt;code&gt;_to&lt;&#x2F;code&gt;.
&lt;code&gt;_data&lt;&#x2F;code&gt; can be attached to this token transaction, but it requires more gas. &lt;code&gt;_data&lt;&#x2F;code&gt; can be empty.&lt;&#x2F;p&gt;
&lt;p&gt;NOTE: A possible way to check whether the &lt;code&gt;_to&lt;&#x2F;code&gt; is a contract or an address is to assemble the code of &lt;code&gt;_to&lt;&#x2F;code&gt;. If there is no code in &lt;code&gt;_to&lt;&#x2F;code&gt;, then this is an externally owned address, otherwise it&#x27;s a contract. If &lt;code&gt;transfer&lt;&#x2F;code&gt; function is &lt;code&gt;payable&lt;&#x2F;code&gt; and ether was deposited then the amount of deposited ether MUST be delivered to &lt;code&gt;_to&lt;&#x2F;code&gt; address alongside tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function of &lt;code&gt;_to&lt;&#x2F;code&gt; MUST be called after all other operations to avoid re-entrancy attacks.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;events&quot;&gt;Events&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;transfer&quot;&gt;&lt;code&gt;Transfer&lt;&#x2F;code&gt;&lt;&#x2F;h5&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _data&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;Triggered when tokens are transferred. Compatible with and similar to the ERC-20 &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;erc-223-token-receiver&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;223&#x2F;&quot;&gt;ERC-223&lt;&#x2F;a&gt; Token Receiver&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;receiver-methods&quot;&gt;Receiver Methods&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&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 function for handling token transfers, which is called from the token contract, when a token holder sends tokens. &lt;code&gt;_from&lt;&#x2F;code&gt; is the address of the sender of the token, &lt;code&gt;_value&lt;&#x2F;code&gt; is the amount of incoming tokens, and &lt;code&gt;_data&lt;&#x2F;code&gt; is attached data similar to &lt;code&gt;msg.data&lt;&#x2F;code&gt; of ether transactions. It works by analogy with the fallback function of Ether transactions and returns nothing.&lt;&#x2F;p&gt;
&lt;p&gt;NOTE: &lt;code&gt;msg.sender&lt;&#x2F;code&gt; will be a token-contract inside the &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function. It may be important to filter which tokens were sent (by token-contract address). The token sender (the person who initiated the token transaction) will be &lt;code&gt;_from&lt;&#x2F;code&gt; inside the &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function. The &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function must return &lt;code&gt;0x8943ec02&lt;&#x2F;code&gt; after handling an incoming token transfer. The &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; function call can be handled by the fallback function of the recipient contact (and in this case it may not return the magic value 0x8943ec02).&lt;&#x2F;p&gt;
&lt;p&gt;IMPORTANT: This function must be named &lt;code&gt;tokenReceived&lt;&#x2F;code&gt; and take parameters &lt;code&gt;address&lt;&#x2F;code&gt;, &lt;code&gt;uint256&lt;&#x2F;code&gt;, &lt;code&gt;bytes&lt;&#x2F;code&gt; to match the function signature &lt;code&gt;0x8943ec02&lt;&#x2F;code&gt;. This function can be manually called by a EOA.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This standard introduces a communication model by enforcing the &lt;code&gt;transfer&lt;&#x2F;code&gt; to execute a handler function in the destination address. This is an important security consideration as it is required that the receiver explicitly implements the token handling function. In cases where the receiver does not implements such function the transfer MUST be reverted.&lt;&#x2F;p&gt;
&lt;p&gt;This standard sticks to the push transaction model where the transfer of assets is initiated on the senders side and handled on the receivers side. As the result, ERC-223 transfers are more gas-efficient while dealing with depositing to contracts as ERC-223 tokens can be deposited with just one transaction while ERC-20 tokens require at least two calls (one for &lt;code&gt;approve&lt;&#x2F;code&gt; and the second that will invoke &lt;code&gt;transferFrom&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; deposit: &lt;code&gt;approve&lt;&#x2F;code&gt; ~46 gas, &lt;code&gt;transferFrom&lt;&#x2F;code&gt; ~75K gas&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;ERC-223 deposit: &lt;code&gt;transfer&lt;&#x2F;code&gt; and handling on the receivers side ~54K gas&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This standard introduces the ability to correct user errors by allowing to handle ANY transactions on the recipients side and reject incorrect or improper transfers. This tokens utilize ONE transferring method for both types of interactions with contracts and externally owned addresses which can simplify the user experience and allow to avoid possible user mistakes.&lt;&#x2F;p&gt;
&lt;p&gt;One downside of the commonly used &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard that ERC-223 is intended to solve is that &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; implements two methods of token transferring: (1) &lt;code&gt;transfer&lt;&#x2F;code&gt; function and (2) &lt;code&gt;approve + transferFrom&lt;&#x2F;code&gt; pattern. Transfer function of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard does not notify the receiver and therefore if any tokens are sent to a contract with the &lt;code&gt;transfer&lt;&#x2F;code&gt; function then the receiver will not recognize this transfer and the tokens can become stuck in the receivers address without any possibility of recovering them. &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;&quot;&gt;ERC-20&lt;&#x2F;a&gt; standard places the burden of determining the transferring method on the user and if the incorrect method is chosen the user can lose the transferred tokens. ERC-223 automatically determines the transferring method, preventing the user from losing tokens due to choosing wrong method.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-223 is intended to simplify the interaction with contracts that are intended to work with tokens. ERC-223 utilizes a &quot;deposit&quot; pattern, similar to that of plain Ether. An ERC-223 deposit to a contract is a simple call of the &lt;code&gt;transfer&lt;&#x2F;code&gt; function. This is one transaction as opposed to two step process of &lt;code&gt;approve + transferFrom&lt;&#x2F;code&gt; depositing.&lt;&#x2F;p&gt;
&lt;p&gt;This standard allows payloads to be attached to transactions using the &lt;code&gt;bytes calldata _data&lt;&#x2F;code&gt; parameter, which can encode a second function call in the destination address, similar to how &lt;code&gt;msg.data&lt;&#x2F;code&gt; does in an ether transaction, or allow for public logging on chain should it be necessary for financial transactions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The interface of this token is similar to that of ERC-20 and most functions serve the same purpose as their analogues in ERC-20.
&lt;code&gt;transfer(address, uint256, bytes calldata)&lt;&#x2F;code&gt; function is not backwards compatible with ERC-20 interface.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-20 tokens can be delivered to a non-contract address with &lt;code&gt;transfer&lt;&#x2F;code&gt; function. ERC-20 tokens can be deposited to a contract address with &lt;code&gt;approve&lt;&#x2F;code&gt; + &lt;code&gt;transferFrom&lt;&#x2F;code&gt; pattern. Depositing ERC-20 tokens to the contract address with &lt;code&gt;transfer&lt;&#x2F;code&gt; function will always result in token deposit not being recognized by the recipient contract.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example of the contract code that handles ERC-20 token deposit. The following contract can accepts &lt;code&gt;tokenA&lt;&#x2F;code&gt; deposits. It is impossible to prevent deposits of non-tokenA to this contract. If tokenA is deposited with &lt;code&gt;transfer&lt;&#x2F;code&gt; function then it will result in a loss of tokens for the depositor because the balance of the user will be decreased in the contract of tokenA but the value of &lt;code&gt;deposits&lt;&#x2F;code&gt; variable in the &lt;code&gt;ERC20Receiver&lt;&#x2F;code&gt; will not be increased i.e. the deposit will not be credited. As of 5&#x2F;9&#x2F;2023 &lt;strong&gt;$201M worth of 50 examined ERC-20 tokens are already lost&lt;&#x2F;strong&gt; in this way on Ethereum mainnet.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC20Receiver&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; tokenA&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&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 class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_token &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; tokenA&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        IERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_token&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&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&gt;        deposits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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&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;ERC-223 tokens must be delivered to non-contract address or contract address in the same way with &lt;code&gt;transfer&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example of the contract code that handles ERC-223 token deposit. The following contract can filter tokens and only accepts &lt;code&gt;tokenA&lt;&#x2F;code&gt;. Other ERC-223 tokens would be rejected.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC223Receiver&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 class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; tokenA&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; deposits&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tokenA&lt;&#x2F;span&gt;&lt;span&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&gt;        deposits&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_from&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x8943ec02&lt;&#x2F;span&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;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;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;&#x2F;h2&gt;
&lt;p&gt;This token utilizes the model similar to plain ether behavior. Therefore replay issues must be taken into account.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ^0.8.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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;library&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns true if `account` is a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * This test is non-exhaustive, and there may be false-negatives: during the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * execution of a contract&amp;#39;s constructor, its address will be reported as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * not containing a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &amp;gt; It is unsafe to assume that an address for which this function returns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * false is an externally-owned account (EOA) and not a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This method relies in extcodesize, which returns 0 for contracts in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; construction, since the code is only stored at the end of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; constructor execution.&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 class=&quot;z-support&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; solhint-disable&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;-next-line no-inline-assembly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        assembly&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; extcodesize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;abstract&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; IERC223Recipient&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Standard ERC-223 receiving function that will handle incoming token transfers.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Token sender address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Amount of tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Transaction metadata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; tokenReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@title&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Reference implementation of the ERC223 standard token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ERC223Token&lt;&#x2F;span&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 class=&quot;z-comment&quot;&gt;     &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Event that is fired on successful transfer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span&gt; _symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   private&lt;&#x2F;span&gt;&lt;span&gt; _decimals&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _totalSupply&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; List of user balances.&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Sets the values for {name} and {symbol}, initializes {decimals} with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * a default value of 18.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * To select a different value for {decimals}, use {_setupDecimals}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * All three of these values are immutable: they can only be set once during&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * construction.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&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 class=&quot;z-storage z-type&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; new_name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; new_symbol&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; new_decimals&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _name     &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; new_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&gt;        _symbol   &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; new_symbol&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _decimals &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; new_decimals&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the name of the token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the symbol of the token, usually a shorter version of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _symbol&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns the number of decimals used to get its user representation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * For example, if `decimals` equals `2`, a balance of `505` tokens should&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * be displayed to a user as `5,05` (`505 &#x2F; 10 ** 2`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Tokens usually opt for a value of 18, imitating the relationship between&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * Ether and Wei. This is the value {ERC223} uses, unless {_setupDecimals} is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * called.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;NOTE&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: This information is only used for _display_ purposes: it in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * no way affects any of the arithmetic of the contract, including&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * {IERC223-balanceOf} and {IERC223-transfer}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decimals&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint8&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _decimals&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC223-totalSupply}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _totalSupply&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; See {IERC223-standard}.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; standard&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;223&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&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&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Returns balance of the `_owner`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;   The address whose balance will be returned.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Balance of the `_owner`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_owner&lt;&#x2F;span&gt;&lt;span&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer the specified amount of tokens to the specified address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      Invokes the `tokenFallback` function if the recipient is a contract.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      The token transfer fails if the recipient is a contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      but does not implement the `tokenFallback` function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      or the fallback function to receive funds.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Receiver address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Amount of tokens that will be transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  Transaction metadata.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Standard function transfer similar to ERC20 transfer with no _data .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Added due to backwards compatibility reasons .&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;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&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&gt;        balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            IERC223Recipient&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;tokenReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _data&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _data&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Transfer the specified amount of tokens to the specified address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      This function works the same with the previous one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      but doesn&amp;#39;t contain `_data` param.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *      Added due to backwards compatibility reasons.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;    Receiver address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     * &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;@param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Amount of tokens that will be transferred.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; _empty &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;00000000&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&gt;        balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&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&gt;        balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; balances&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;isContract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;            IERC223Recipient&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;tokenReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _empty&lt;&#x2F;span&gt;&lt;span&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&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _empty&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Homestead&quot;</title>
        <published>2017-04-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/606/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/606/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:606"
            label="EIP-606" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/606/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specifies the changes included in the hard fork named Homestead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Homestead&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block &amp;gt;= 1,150,000 on Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 494,000 on Morden&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 0 on future testnets&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Included EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;2&#x2F;&quot;&gt;EIP-2&lt;&#x2F;a&gt; (Homestead Hard-fork Changes)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;7&#x2F;&quot;&gt;EIP-7&lt;&#x2F;a&gt; (DELEGATECALL)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;8&#x2F;&quot;&gt;EIP-8&lt;&#x2F;a&gt; (Networking layer: devp2p Forward Compatibility Requirements for Homestead)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;02&#x2F;29&#x2F;homestead-release&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Spurious Dragon&quot;</title>
        <published>2017-04-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/607/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/607/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:607"
            label="EIP-607" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/607/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specifies the changes included in the hard fork named Spurious Dragon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Spurious Dragon&lt;&#x2F;li&gt;
&lt;li&gt;Aliases: State-clearing&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block &amp;gt;= 2,675,000 on Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 1,885,000 on Morden&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Included EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;155&#x2F;&quot;&gt;EIP-155&lt;&#x2F;a&gt; (Simple replay attack protection)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;160&#x2F;&quot;&gt;EIP-160&lt;&#x2F;a&gt; (EXP cost increase)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;161&#x2F;&quot;&gt;EIP-161&lt;&#x2F;a&gt; (State trie clearing)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;170&#x2F;&quot;&gt;EIP-170&lt;&#x2F;a&gt; (Contract code size limit)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;11&#x2F;18&#x2F;hard-fork-no-4-spurious-dragon&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Tangerine Whistle&quot;</title>
        <published>2017-04-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/608/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/608/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:608"
            label="EIP-608" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/608/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specifies the changes included in the hard fork named Tangerine Whistle (EIP 150).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Tangerine Whistle&lt;&#x2F;li&gt;
&lt;li&gt;Aliases: EIP 150, Anti-DoS&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block &amp;gt;= 2,463,000 on Mainnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Included EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;150&#x2F;&quot;&gt;EIP-150&lt;&#x2F;a&gt; (Gas cost changes for IO-heavy operations)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;10&#x2F;13&#x2F;announcement-imminent-hard-fork-eip150-gas-cost-changes&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;10&#x2F;18&#x2F;faq-upcoming-ethereum-hard-fork&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;Hardfork Meta: Byzantium&quot;</title>
        <published>2017-04-23T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/609/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/609/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:609"
            label="EIP-609" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/609/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This specifies the changes included in the hard fork named Byzantium.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Codename: Byzantium&lt;&#x2F;li&gt;
&lt;li&gt;Aliases: Metropolis&#x2F;Byzantium, Metropolis part 1&lt;&#x2F;li&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block &amp;gt;= 4,370,000 on Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 1,700,000 on Ropsten testnet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Included EIPs:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;100&#x2F;&quot;&gt;EIP-100&lt;&#x2F;a&gt; (Change difficulty adjustment to target mean block time including uncles)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;140&#x2F;&quot;&gt;EIP-140&lt;&#x2F;a&gt; (REVERT instruction in the Ethereum Virtual Machine)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;196&#x2F;&quot;&gt;EIP-196&lt;&#x2F;a&gt; (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;197&#x2F;&quot;&gt;EIP-197&lt;&#x2F;a&gt; (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;198&#x2F;&quot;&gt;EIP-198&lt;&#x2F;a&gt; (Precompiled contract for bigint modular exponentiation)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;211&#x2F;&quot;&gt;EIP-211&lt;&#x2F;a&gt; (New opcodes: RETURNDATASIZE and RETURNDATACOPY)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;214&#x2F;&quot;&gt;EIP-214&lt;&#x2F;a&gt; (New opcode STATICCALL)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;649&#x2F;&quot;&gt;EIP-649&lt;&#x2F;a&gt; (Difficulty Bomb Delay and Block Reward Reduction)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;658&#x2F;&quot;&gt;EIP-658&lt;&#x2F;a&gt; (Embedding transaction status code in receipts)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2017&#x2F;10&#x2F;12&#x2F;byzantium-hf-announcement&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum purpose allocation for Deterministic Wallets</title>
        <published>2017-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><uri>https://github.com/arachnid</uri>
	</author>
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/micahzoltu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/600/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742" />
        

        <id>https://wg-eips.ritovision.com/600/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:600"
            label="ERC-600" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/600/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a logical hierarchy for deterministic wallets based on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0032.mediawiki&quot;&gt;BIP32&lt;&#x2F;a&gt;, the purpose scheme defined in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0043.mediawiki&quot;&gt;BIP43&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;pull&#x2F;523&quot;&gt;this proposed change to BIP43&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP is a particular application of BIP43.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Because Ethereum is based on account balances rather than UTXO, the hierarchy defined by BIP44 is poorly suited. As a result, several competing derivation path strategies have sprung up for deterministic wallets, resulting in inter-client incompatibility. This BIP seeks to provide a path to standardise this in a fashion better suited to Ethereum&#x27;s unique requirements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We define the following 2 levels in BIP32 path:&lt;&#x2F;p&gt;
&lt;pre&gt;
m &#x2F; purpose&#x27; &#x2F; subpurpose&#x27; &#x2F; EIP&#x27;
&lt;&#x2F;pre&gt;
&lt;p&gt;Apostrophe in the path indicates that BIP32 hardened derivation is used.&lt;&#x2F;p&gt;
&lt;p&gt;Each level has a special meaning, described in the chapters below.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;purpose&quot;&gt;Purpose&lt;&#x2F;h3&gt;
&lt;p&gt;Purpose is set to 43, as documented in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;pull&#x2F;523&quot;&gt;this proposed change to BIP43&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The purpose field indicates that this path is for a non-bitcoin cryptocurrency.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;subpurpose&quot;&gt;Subpurpose&lt;&#x2F;h3&gt;
&lt;p&gt;Subpurpose is set to 60, the SLIP-44 code for Ethereum.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eip&quot;&gt;EIP&lt;&#x2F;h3&gt;
&lt;p&gt;EIP is set to the EIP number specifying the remainder of the BIP32 derivation path. This permits new Ethereum-focused applications of deterministic wallets without needing to interface with the BIP process.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The existing convention is to use the &#x27;Ethereum&#x27; coin type, leading to paths starting with &lt;code&gt;m&#x2F;44&#x27;&#x2F;60&#x27;&#x2F;*&lt;&#x2F;code&gt;. Because this still assumes a UTXO-based coin, we contend that this is a poor fit, resulting in standardisation, usability, and security compromises. As a result, we are making the above proposal to define an entirely new hierarchy for Ethereum-based chains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The introduction of another derivation path requires existing software to add support for this scheme in addition to any existing schemes. Given the already confused nature of wallet derivation paths in Ethereum, we anticipate this will cause relatively little additional disruption, and has the potential to improve matters significantly in the long run.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;TBD&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;None yet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;84&quot;&gt;This discussion on derivation paths&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum hierarchy for deterministic wallets</title>
        <published>2017-04-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><uri>https://github.com/arachnid</uri>
	</author>
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/micahzoltu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/601/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742" />
        

        <id>https://wg-eips.ritovision.com/601/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:601"
            label="ERC-601" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/601/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP defines a logical hierarchy for deterministic wallets based on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0032.mediawiki&quot;&gt;BIP32&lt;&#x2F;a&gt;, the purpose scheme defined in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0043.mediawiki&quot;&gt;BIP43&lt;&#x2F;a&gt; and eip-draft-ethereum-purpose.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP is a particular application of eip-draft-ethereum-purpose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;At present, different Ethereum clients and wallets use different derivation paths; a summary of them can be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;84#issuecomment-292324521&quot;&gt;here&lt;&#x2F;a&gt;. Some of these paths violate BIP44, the standard defining derivation paths starting with &lt;code&gt;m&#x2F;44&#x27;&#x2F;&lt;&#x2F;code&gt;. This creates confusion and incompatibility between wallet implementations, in some cases making funds from one wallet inaccessible on another, and in others requiring prompting users manually for a derivation path, which hinders usability.&lt;&#x2F;p&gt;
&lt;p&gt;Further, BIP44 was designed with UTXO-based blockchains in mind, and is a poor fit for Ethereum, which uses an accounts abstraction instead.&lt;&#x2F;p&gt;
&lt;p&gt;As an alternative, we propose a deterministic wallet hierarchy better tailored to Ethereum&#x27;s unique requirements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We define the following 4 levels in BIP32 path:&lt;&#x2F;p&gt;
&lt;pre&gt;
m &#x2F; purpose&#x27; &#x2F; subpurpose&#x27; &#x2F; EIP&#x27; &#x2F; wallet&#x27;
&lt;&#x2F;pre&gt;
&lt;p&gt;Apostrophe in the path indicates that BIP32 hardened derivation is used.&lt;&#x2F;p&gt;
&lt;p&gt;Each level has a special meaning, described in the chapters below.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;purpose&quot;&gt;Purpose&lt;&#x2F;h3&gt;
&lt;p&gt;Purpose is a constant set to 43, indicating the key derivation is for a non-bitcoin cryptocurrency.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;subpurpose&quot;&gt;Subpurpose&lt;&#x2F;h3&gt;
&lt;p&gt;Subpurpose is set to 60, the SLIP-44 code for Ethereum.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eip&quot;&gt;EIP&lt;&#x2F;h3&gt;
&lt;p&gt;EIP is set to the EIP number specifying the remainder of the BIP32 derivation path. For paths following this EIP specification, the number assigned to this EIP is used.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wallet&quot;&gt;Wallet&lt;&#x2F;h3&gt;
&lt;p&gt;This component of the path splits the wallet into different user identities, allowing a single wallet to have multiple public identities.&lt;&#x2F;p&gt;
&lt;p&gt;Accounts are numbered from index 0 in sequentially increasing manner. This number is used as child index in BIP32 derivation.&lt;&#x2F;p&gt;
&lt;p&gt;Hardened derivation is used at this level.&lt;&#x2F;p&gt;
&lt;p&gt;Software should prevent a creation of an account if a previous account does not have a transaction history (meaning its address has not been used before).&lt;&#x2F;p&gt;
&lt;p&gt;Software needs to discover all used accounts after importing the seed from an external source.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The existing convention is to use the &#x27;Ethereum&#x27; coin type, leading to paths starting with &lt;code&gt;m&#x2F;44&#x27;&#x2F;60&#x27;&#x2F;*&lt;&#x2F;code&gt;. Because this still assumes a UTXO-based coin, we contend that this is a poor fit, resulting in standardisation, usability, and security compromises. As a result, we are making the above proposal to define an entirely new hierarchy for Ethereum-based chains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The introduction of another derivation path requires existing software to add support for this scheme in addition to any existing schemes. Given the already confused nature of wallet derivation paths in Ethereum, we anticipate this will cause relatively little additional disruption, and has the potential to improve matters significantly in the long run.&lt;&#x2F;p&gt;
&lt;p&gt;For applications that utilise mnemonics, the authors expect to submit another EIP draft that describes a method for avoiding backwards compatibility concerns when transitioning to this new derivation path.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;TBD&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;None yet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;84&quot;&gt;This discussion on derivation paths&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Add `blockHash` to JSON-RPC filter options.</title>
        <published>2017-03-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Micah Zoltu</name><uri>https://github.com/MicahZoltu</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/234/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/234" />
        

        <id>https://wg-eips.ritovision.com/234/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        

        
        <category
            term="tag:eip:234"
            label="EIP-234" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/234/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Add an option to JSON-RPC filter options (used by &lt;code&gt;eth_newFilter&lt;&#x2F;code&gt; and &lt;code&gt;eth_getLogs&lt;&#x2F;code&gt;) that allows specifying the block hash that should be included in the results.  This option would be an alternative to &lt;code&gt;fromBlock&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;toBlock&lt;&#x2F;code&gt; options.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This addition would allow clients to fetch logs for specific blocks, whether those blocks were in the current main chain or not.  This resolves some issues that make it difficult&#x2F;expensive to author robust clients due to the nature of chain reorgs, unreliable network connections and the result set not containing enough details in the empty case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The filter options used by &lt;code&gt;eth_newFilter&lt;&#x2F;code&gt; would have an additional optional parameter named &lt;code&gt;blockHash&lt;&#x2F;code&gt; whose value is a single block hash.  The Ethereum node responding to the request would either send back an error if the block hash was not found or it would return the results matching the filter (per normal operation) constrained to the block provided.  Internally, this would function (presumably) similar to the &lt;code&gt;fromBlock&lt;&#x2F;code&gt; and &lt;code&gt;toBlock&lt;&#x2F;code&gt; filter options.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;A client (dApp) who needs reliable notification of both log additions (on new blocks) and log removals (on chain reorgs) cannot achieve this while relying solely on subscriptions and filters.  This is because a combination of a network or remote node failure during a reorg can result in the client getting out of sync with reality.  An example of where this can happen with Websockets is when the client opens a web socket connection, sets up a log filter subscription, gets notified of some new logs, then loses the web socket connection, then (while disconnected) a re-org occurs, then the client connects back and establishes a new log filter.  In this scenario they will not receive notification of the log removals from the node because they were disconnected when the removals were broadcast and the loss of their connection resulted in the node forgetting about their existence.  A similar scenario can be concocted for HTTP clients where between polls for updates, the node goes down and comes back (resulting in loss of filter state) and a re-org also occurs between the same two polls.&lt;&#x2F;p&gt;
&lt;p&gt;In order to deal with this while still providing a robust mechanism for internal block&#x2F;log additional&#x2F;removal, the client can maintain a blockchain internally (last &lt;code&gt;n&lt;&#x2F;code&gt; blocks) and only subscribe&#x2F;poll for new blocks.  When a new block is received, the client can reconcile their internal model with the new block, potentially back-filling parents or rolling back&#x2F;removing blocks from their internal model to get in sync with the node.  This can account for any type of disconnect&#x2F;reorg&#x2F;outage scenario and also allows the client (as an added benefit) to talk to a cluster of Ethereum nodes (e.g., via round-robin) rather than being tightly coupled to a single node.&lt;&#x2F;p&gt;
&lt;p&gt;Once the user has a reliable stream of blocks, they can then look at the bloom filter for the new block and if the block &lt;em&gt;may&lt;&#x2F;em&gt; have logs of interest they can fetch the filtered logs for that block from the node.  The problem that arises is that a re-org may occur between when the client receives the block and when the client fetches the logs for that block.  Given the current set of filter options, the client can only ask for logs by block number.  In this scenario, the logs they get back will be for a block that &lt;em&gt;isn&#x27;t&lt;&#x2F;em&gt; the block they want the logs for and is instead for a block that was re-orged in (and may not be fully reconciled with the internal client state).  This can be partially worked around by looking at the resulting logs themselves and identifying whether or not they are for the block hash requested.  However, if the result set is an empty array (no logs fetched) then the client is in a situation where they don&#x27;t know what block the results are for.  The results could have been legitimately empty (bloom filter can yield false positives) for the block in question, or they could be receiving empty logs for a block that they don&#x27;t know about.  At this point, there is no decision the client can make that allows them a guarantee of recovery.  They can assume the empty logs were for the correct block, but if they weren&#x27;t then they will never try to fetch again.  This creates a problem if the block was only transiently re-orged out because it may come back before the next block poll so the client will never witness the reorg.  They can assume the empty logs were for the wrong block, and refetch them, but they may continue to get empty results putting them right back into the same situation.&lt;&#x2F;p&gt;
&lt;p&gt;By adding the ability to fetch logs by hash, the client can be guaranteed that if they get a result set, it is for the block in question.  If they get an error, then they can take appropriate action (e.g., rollback that block client-side and re-fetch latest).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The only potential issue here is the &lt;code&gt;fromBlock&lt;&#x2F;code&gt; and &lt;code&gt;toBlock&lt;&#x2F;code&gt; fields.  It wouldn&#x27;t make sense to include both the hash and the number so it seems like &lt;code&gt;fromBlock&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;toBlock&lt;&#x2F;code&gt; should be mutually exclusive with &lt;code&gt;blockHash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;{ &quot;jsonrpc&quot;: &quot;2.0&quot;, &quot;id&quot;: 1, &quot;method&quot;: &quot;eth_getLogs&quot;, params: [{&quot;blockHash&quot;: &quot;0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c&quot;}] }&lt;&#x2F;code&gt; should return all of the logs for the block with hash &lt;code&gt;0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c&lt;&#x2F;code&gt;.  If a &lt;code&gt;topics&lt;&#x2F;code&gt; field is added to the filter options then a filtered set of logs for that block should be returned.  If no block exists with that hash then an error should be returned with a &lt;code&gt;code&lt;&#x2F;code&gt; of &lt;code&gt;-32000&lt;&#x2F;code&gt;, a &lt;code&gt;message&lt;&#x2F;code&gt; of &lt;code&gt;&quot;Block not found.&quot;&lt;&#x2F;code&gt; and a &lt;code&gt;data&lt;&#x2F;code&gt; of &lt;code&gt;&quot;0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot; checked=&quot;&quot;&#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;16734&quot;&gt;Geth&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Clique proof-of-authority consensus protocol</title>
        <published>2017-03-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Péter Szilágyi</name><email>peterke@gmail.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/225/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/225" />
        

        <id>https://wg-eips.ritovision.com/225/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:225"
            label="EIP-225" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/225/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Clique is a proof-of-authority consensus protocol. It shadows the design of Ethereum mainnet, so it can be added to any client with minimal effort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Ethereum&#x27;s first official testnet was Morden. It ran from July 2015 to about November 2016, when due to the accumulated junk and some testnet consensus issues between Geth and Parity, it was finally laid to rest in favor of a testnet reboot.&lt;&#x2F;p&gt;
&lt;p&gt;Ropsten was thus born, clearing out all the junk and starting with a clean slate. This ran well until the end of February 2017, when malicious actors decided to abuse the low PoW and gradually inflate the block gas limits to 9 billion (from the normal 4.7 million), at which point sending in gigantic transactions crippling the entire network. Even before that, attackers attempted multiple extremely long reorgs, causing network splits between different clients, and even different versions.&lt;&#x2F;p&gt;
&lt;p&gt;The root cause of these attacks is that a PoW network is only as secure as the computing capacity placed behind it. Restarting a new testnet from zero wouldn&#x27;t solve anything, since the attacker can mount the same attack over and over again. The Parity team decided to go with an emergency solution of rolling back a significant number of blocks, and enacting a soft-fork rule that disallows gas limits above a certain threshold.&lt;&#x2F;p&gt;
&lt;p&gt;While this solution may work in the short term:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It&#x27;s not elegant: Ethereum supposed to have dynamic block limits&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s not portable: other clients need to implement new fork logic themselves&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s not compatible with sync modes: fast and light clients are both out of luck&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s just prolonging the attacks: junk can still be steadily pushed in ad infinitum&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Parity&#x27;s solution although not perfect, is nonetheless workable. I&#x27;d like to propose a longer term alternative solution, which is more involved, yet should be simple enough to allow rolling out in a reasonable amount of time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;standardized-proof-of-authority&quot;&gt;Standardized proof-of-authority&lt;&#x2F;h3&gt;
&lt;p&gt;As reasoned above, proof-of-work cannot work securely in a network with no value. Ethereum has its long term goal of proof-of-stake based on Casper, but that is heavy research so we cannot rely on that any time soon to fix today&#x27;s problems. One solution however is easy enough to implement, yet effective enough to fix the testnet properly, namely a proof-of-authority scheme.&lt;&#x2F;p&gt;
&lt;p&gt;The main design goals of the PoA protocol described here is that it should be very simple to implement and embed into any existing Ethereum client, while at the same time allow using existing sync technologies (fast, light, warp) without needing client developers to add custom logic to critical software.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;design-constraints&quot;&gt;Design constraints&lt;&#x2F;h2&gt;
&lt;p&gt;There are two approaches to syncing a blockchain in general:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The classical approach is to take the genesis block and crunch through all the transactions one by one. This is tried and proven, but in Ethereum complexity networks quickly turns out to be very costly computationally.&lt;&#x2F;li&gt;
&lt;li&gt;The other is to only download the chain of block headers and verify their validity, after which point an arbitrary recent state may be downloaded from the network and checked against recent headers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A PoA scheme is based on the idea that blocks may only be minted by trusted signers. As such, every block (or header) that a client sees can be matched against the list of trusted signers. The challenge here is how to maintain a list of authorized signers that can change in time? The obvious answer (store it in an Ethereum contract) is also the wrong answer: fast, light and warp sync don&#x27;t have access to the state during syncing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The protocol of maintaining the list of authorized signers must be fully contained in the block headers.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The next obvious idea would be to change the structure of the block headers so it drops the notions of PoW, and introduces new fields to cater for voting mechanisms. This is also the wrong answer: changing such a core data structure in multiple implementations would be a nightmare development, maintenance and security wise.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The protocol of maintaining the list of authorized signers must fit fully into the current data models.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, according to the above, we can&#x27;t use the EVM for voting, rather have to resort to headers. And we can&#x27;t change header fields, rather have to resort to the currently available ones. Not much wiggle room.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;repurposing-header-fields-for-signing-and-voting&quot;&gt;Repurposing header fields for signing and voting&lt;&#x2F;h3&gt;
&lt;p&gt;The most obvious field that currently is used solely as &lt;em&gt;fun metadata&lt;&#x2F;em&gt; is the 32 byte &lt;strong&gt;extra-data&lt;&#x2F;strong&gt; section in block headers. Miners usually place their client and version in there, but some fill it with alternative &quot;messages&quot;. The protocol would extend this field &lt;del&gt;to&lt;&#x2F;del&gt; with 65 bytes with the purpose of a secp256k1 miner signature. This would allow anyone obtaining a block to verify it against a list of authorized signers. It also makes the &lt;strong&gt;miner&lt;&#x2F;strong&gt; section in block headers obsolete (since the address can be derived from the signature).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note, changing the length of a header field is a non invasive operation as all code (such as RLP encoding, hashing) is agnostic to that, so clients wouldn&#x27;t need custom logic.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The above is enough to validate a chain, but how can we update a dynamic list of signers. The answer is that we can repurpose the newly obsoleted &lt;strong&gt;miner&lt;&#x2F;strong&gt; field and the PoA obsoleted &lt;strong&gt;nonce&lt;&#x2F;strong&gt; field to create a voting protocol:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;During regular blocks, both of these fields would be set to zero.&lt;&#x2F;li&gt;
&lt;li&gt;If a signer wishes to enact a change to the list of authorized signers, it will:
&lt;ul&gt;
&lt;li&gt;Set the &lt;strong&gt;miner&lt;&#x2F;strong&gt; to the signer it wishes to vote about&lt;&#x2F;li&gt;
&lt;li&gt;Set the &lt;strong&gt;nonce&lt;&#x2F;strong&gt; to &lt;code&gt;0&lt;&#x2F;code&gt; or &lt;code&gt;0xff...f&lt;&#x2F;code&gt; to vote in favor of adding or kicking out&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Any clients syncing the chain can &quot;tally&quot; up the votes during block processing, and maintain a dynamically changing list of authorized signers by popular vote.&lt;&#x2F;p&gt;
&lt;p&gt;To avoid having an infinite window to tally up votes in, and also to allow periodically flushing stale proposals, we can reuse the concept of an epoch from ethash, where every epoch transition flushes all pending votes. Furthermore, these epoch transitions can also act as stateless checkpoints containing the list of current authorized signers within the header extra-data. This permits clients to sync up based only on a checkpoint hash without having to replay all the voting that was done on the chain up to that point. It also allows the genesis header to fully define the chain, containing the list of initial signers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attack-vector-malicious-signer&quot;&gt;Attack vector: Malicious signer&lt;&#x2F;h3&gt;
&lt;p&gt;It may happen that a malicious user gets added to the list of signers, or that a signer key&#x2F;machine is compromised. In such a scenario the protocol needs to be able to defend itself against reorganizations and spamming. The proposed solution is that given a list of N authorized signers, any signer may only mint 1 block out of every K. This ensures that damage is limited, and the remainder of the miners can vote out the malicious user.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attack-vector-censoring-signer&quot;&gt;Attack vector: Censoring signer&lt;&#x2F;h3&gt;
&lt;p&gt;Another interesting attack vector is if a signer (or group of signers) attempts to censor out blocks that vote on removing them from the authorization list. To work around this, we restrict the allowed minting frequency of signers to 1 out of N&#x2F;2. This ensures that malicious signers need to control at least 51% of signing accounts, at which case it&#x27;s game over anyway.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attack-vector-spamming-signer&quot;&gt;Attack vector: Spamming signer&lt;&#x2F;h3&gt;
&lt;p&gt;A final small attack vector is that of malicious signers injecting new vote proposals inside every block they mint. Since nodes need to tally up all votes to create the actual list of authorized signers, they need to track all votes through time. Without placing a limit on the vote window, this could grow slowly, yet unbounded. The solution is to place a &lt;del&gt;moving&lt;&#x2F;del&gt; window of W blocks after which votes are considered stale. &lt;del&gt;A sane window might be 1-2 epochs.&lt;&#x2F;del&gt; We&#x27;ll call this an epoch.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attack-vector-concurrent-blocks&quot;&gt;Attack vector: Concurrent blocks&lt;&#x2F;h3&gt;
&lt;p&gt;If the number of authorized signers are N, and we allow each signer to mint 1 block out of K, then at any point in time N-K+1 miners are allowed to mint. To avoid these racing for blocks, every signer would add a small random &quot;offset&quot; to the time it releases a new block. This ensures that small forks are rare, but occasionally still happen (as on the main net). If a signer is caught abusing it&#x27;s authority and causing chaos, it can be voted out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We define the following constants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;EPOCH_LENGTH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Number of blocks after which to checkpoint and reset the pending votes.
&lt;ul&gt;
&lt;li&gt;Suggested &lt;code&gt;30000&lt;&#x2F;code&gt; for the testnet to remain analogous to the mainnet &lt;code&gt;ethash&lt;&#x2F;code&gt; epoch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;BLOCK_PERIOD&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Minimum difference between two consecutive block&#x27;s timestamps.
&lt;ul&gt;
&lt;li&gt;Suggested &lt;code&gt;15s&lt;&#x2F;code&gt; for the testnet to remain analogous to the mainnet &lt;code&gt;ethash&lt;&#x2F;code&gt; target.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;EXTRA_VANITY&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Fixed number of extra-data prefix bytes reserved for signer &lt;em&gt;vanity&lt;&#x2F;em&gt;.
&lt;ul&gt;
&lt;li&gt;Suggested &lt;code&gt;32 bytes&lt;&#x2F;code&gt; to retain the current extra-data allowance and&#x2F;or use.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;EXTRA_SEAL&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Fixed number of extra-data suffix bytes reserved for signer seal.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;65 bytes&lt;&#x2F;code&gt; fixed as signatures are based on the standard &lt;code&gt;secp256k1&lt;&#x2F;code&gt; curve.&lt;&#x2F;li&gt;
&lt;li&gt;Filled with zeros on genesis block.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NONCE_AUTH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Magic nonce number &lt;code&gt;0xffffffffffffffff&lt;&#x2F;code&gt; to vote on adding a new signer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NONCE_DROP&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Magic nonce number &lt;code&gt;0x0000000000000000&lt;&#x2F;code&gt; to vote on removing a signer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;UNCLE_HASH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Always &lt;code&gt;Keccak256(RLP([]))&lt;&#x2F;code&gt; as uncles are meaningless outside of PoW.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;DIFF_NOTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Block score (difficulty) for blocks containing out-of-turn signatures.
&lt;ul&gt;
&lt;li&gt;Suggested &lt;code&gt;1&lt;&#x2F;code&gt; since it just needs to be an arbitrary baseline constant.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;DIFF_INTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Block score (difficulty) for blocks containing in-turn signatures.
&lt;ul&gt;
&lt;li&gt;Suggested &lt;code&gt;2&lt;&#x2F;code&gt; to show a slight preference over out-of-turn signatures.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We also define the following per-block constants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;BLOCK_NUMBER&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Block height in the chain, where the height of the genesis is block &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;SIGNER_COUNT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Number of authorized signers valid at a particular instance in the chain.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;SIGNER_INDEX&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Zero-based index of the block signer in the sorted list of current authorized signers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;SIGNER_LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Number of consecutive blocks out of which a signer may only sign one.
&lt;ul&gt;
&lt;li&gt;Must be &lt;code&gt;floor(SIGNER_COUNT &#x2F; 2) + 1&lt;&#x2F;code&gt; to enforce majority consensus on a chain.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We repurpose the &lt;code&gt;ethash&lt;&#x2F;code&gt; header fields as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;beneficiary&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; &#x2F; &lt;strong&gt;&lt;code&gt;miner&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Address to propose modifying the list of authorized signers with.
&lt;ul&gt;
&lt;li&gt;Should be filled with zeroes normally, modified only while voting.&lt;&#x2F;li&gt;
&lt;li&gt;Arbitrary values are permitted nonetheless (even meaningless ones such as voting out non signers) to avoid extra complexity in implementations around voting mechanics.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be filled with zeroes on checkpoint (i.e. epoch transition) blocks.&lt;&#x2F;li&gt;
&lt;li&gt;Transaction execution &lt;strong&gt;must&lt;&#x2F;strong&gt; use the actual block signer (see &lt;code&gt;extraData&lt;&#x2F;code&gt;) for the &lt;code&gt;COINBASE&lt;&#x2F;code&gt; opcode and transaction fees &lt;strong&gt;must&lt;&#x2F;strong&gt; be attributed to the signer account.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;nonce&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Signer proposal regarding the account defined by the &lt;code&gt;beneficiary&lt;&#x2F;code&gt; field.
&lt;ul&gt;
&lt;li&gt;Should be &lt;strong&gt;&lt;code&gt;NONCE_DROP&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; to propose deauthorizing &lt;code&gt;beneficiary&lt;&#x2F;code&gt; as an existing signer.&lt;&#x2F;li&gt;
&lt;li&gt;Should be &lt;strong&gt;&lt;code&gt;NONCE_AUTH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; to propose authorizing &lt;code&gt;beneficiary&lt;&#x2F;code&gt; as a new signer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be filled with zeroes on checkpoint (i.e. epoch transition) blocks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; not take up any other value apart from the two above (for now).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;extraData&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Combined field for signer vanity, checkpointing and signer signatures.
&lt;ul&gt;
&lt;li&gt;First &lt;strong&gt;&lt;code&gt;EXTRA_VANITY&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; bytes (fixed) may contain arbitrary signer vanity data.&lt;&#x2F;li&gt;
&lt;li&gt;Last &lt;strong&gt;&lt;code&gt;EXTRA_SEAL&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; bytes (fixed) is the signer&#x27;s signature sealing the header.&lt;&#x2F;li&gt;
&lt;li&gt;Checkpoint blocks &lt;strong&gt;must&lt;&#x2F;strong&gt; contain a list of signers (&lt;code&gt;N*20 bytes&lt;&#x2F;code&gt;) in between, &lt;strong&gt;omitted&lt;&#x2F;strong&gt; otherwise.&lt;&#x2F;li&gt;
&lt;li&gt;The list of signers in checkpoint block extra-data sections &lt;strong&gt;must&lt;&#x2F;strong&gt; be sorted in ascending byte order.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mixHash&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Reserved for fork protection logic, similar to the extra-data during the DAO.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be filled with zeroes during normal operation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ommersHash&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; be &lt;strong&gt;&lt;code&gt;UNCLE_HASH&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; as uncles are meaningless outside of PoW.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;timestamp&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: &lt;strong&gt;Must&lt;&#x2F;strong&gt; be at least the parent timestamp + &lt;strong&gt;&lt;code&gt;BLOCK_PERIOD&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;difficulty&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: Contains the standalone score of the block to derive the quality of a chain.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be &lt;strong&gt;&lt;code&gt;DIFF_NOTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; if &lt;code&gt;BLOCK_NUMBER % SIGNER_COUNT != SIGNER_INDEX&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Must&lt;&#x2F;strong&gt; be &lt;strong&gt;&lt;code&gt;DIFF_INTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; if &lt;code&gt;BLOCK_NUMBER % SIGNER_COUNT == SIGNER_INDEX&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;authorizing-a-block&quot;&gt;Authorizing a block&lt;&#x2F;h3&gt;
&lt;p&gt;To authorize a block for the network, the signer needs to sign the block&#x27;s sighash containing &lt;strong&gt;everything except the signature itself&lt;&#x2F;strong&gt;. This means that this hash contains every field of the header (&lt;code&gt;nonce&lt;&#x2F;code&gt; and &lt;code&gt;mixDigest&lt;&#x2F;code&gt; included), and also the  &lt;code&gt;extraData&lt;&#x2F;code&gt; with the exception of the 65 byte signature suffix. The fields are hashed in the order of their definition in the yellow paper. Note that this sighash differs from the final block hash which also includes the signature.&lt;&#x2F;p&gt;
&lt;p&gt;The sighash is signed using the standard &lt;code&gt;secp256k1&lt;&#x2F;code&gt; curve, and the resulting 65 byte signature (&lt;code&gt;R&lt;&#x2F;code&gt;, &lt;code&gt;S&lt;&#x2F;code&gt;, &lt;code&gt;V&lt;&#x2F;code&gt;, where &lt;code&gt;V&lt;&#x2F;code&gt; is &lt;code&gt;0&lt;&#x2F;code&gt; or &lt;code&gt;1&lt;&#x2F;code&gt;) is embedded into the &lt;code&gt;extraData&lt;&#x2F;code&gt; as the trailing 65 byte suffix.&lt;&#x2F;p&gt;
&lt;p&gt;To ensure malicious signers (loss of signing key) cannot wreck havoc in the network, each signer is allowed to sign &lt;strong&gt;maximum one&lt;&#x2F;strong&gt; out of &lt;strong&gt;&lt;code&gt;SIGNER_LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; consecutive blocks. The order is not fixed, but in-turn signing weighs more (&lt;strong&gt;&lt;code&gt;DIFF_INTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;) than out of turn one (&lt;strong&gt;&lt;code&gt;DIFF_NOTURN&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;authorization-strategies&quot;&gt;Authorization strategies&lt;&#x2F;h4&gt;
&lt;p&gt;As long as signers conform to the above specs, they can authorize and distribute blocks as they see fit. The following suggested strategy will however reduce network traffic and small forks, so it&#x27;s a suggested feature:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If a signer is allowed to sign a block (is on the authorized list and didn&#x27;t sign recently).
&lt;ul&gt;
&lt;li&gt;Calculate the optimal signing time of the next block (parent + &lt;strong&gt;&lt;code&gt;BLOCK_PERIOD&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;If the signer is in-turn, wait for the exact time to arrive, sign and broadcast immediately.&lt;&#x2F;li&gt;
&lt;li&gt;If the signer is out-of-turn, delay signing by &lt;code&gt;rand(SIGNER_COUNT * 500ms)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This small strategy will ensure that the in-turn signer (who&#x27;s block weighs more) has a slight advantage to sign and propagate versus the out-of-turn signers. Also the scheme allows a bit of scale with the increase of the number of signers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;voting-on-signers&quot;&gt;Voting on signers&lt;&#x2F;h3&gt;
&lt;p&gt;Every epoch transition (genesis block included) acts as a stateless checkpoint, from which capable clients should be able to sync without requiring any previous state. This means epoch headers &lt;strong&gt;must not&lt;&#x2F;strong&gt; contain votes, all non settled votes are discarded, and tallying starts from scratch.&lt;&#x2F;p&gt;
&lt;p&gt;For all non-epoch transition blocks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Signers may cast one vote per own block to propose a change to the authorization list.&lt;&#x2F;li&gt;
&lt;li&gt;Only the latest proposal per target beneficiary is kept from a single signer.&lt;&#x2F;li&gt;
&lt;li&gt;Votes are tallied live as the chain progresses (concurrent proposals allowed).&lt;&#x2F;li&gt;
&lt;li&gt;Proposals reaching majority consensus &lt;strong&gt;&lt;code&gt;SIGNER_LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; come into effect immediately.&lt;&#x2F;li&gt;
&lt;li&gt;Invalid proposals are &lt;strong&gt;not&lt;&#x2F;strong&gt; to be penalized for client implementation simplicity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;A proposal coming into effect entails discarding all pending votes for that proposal (both for and against) and starting with a clean slate.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cascading-votes&quot;&gt;Cascading votes&lt;&#x2F;h4&gt;
&lt;p&gt;A complex corner case may arise during signer deauthorization. When a previously authorized signer is dropped, the number of signers required to approve a proposal might decrease by one. This might cause one or more pending proposals to reach majority consensus, the execution of which might further cascade into new proposals passing.&lt;&#x2F;p&gt;
&lt;p&gt;Handling this scenario is non obvious when multiple conflicting proposals pass simultaneously (e.g. add a new signer vs. drop an existing one), where the evaluation order might drastically change the outcome of the final authorization list. Since signers may invert their own votes in every block they mint, it&#x27;s not so obvious which proposal would be &quot;first&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;To avoid the pitfalls cascading executions would entail, the Clique proposal explicitly forbids cascading effects. In other words: &lt;strong&gt;Only the &lt;code&gt;beneficiary&lt;&#x2F;code&gt; of the current header&#x2F;vote may be added to&#x2F;dropped from the authorization list. If that causes other proposals to reach consensus, those will be executed when their respective beneficiaries are &quot;touched&quot; again (given that majority consensus still holds at that point).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;voting-strategies&quot;&gt;Voting strategies&lt;&#x2F;h4&gt;
&lt;p&gt;Since the blockchain can have small reorgs, a naive voting mechanism of &quot;cast-and-forget&quot; may not be optimal, since a block containing a singleton vote may not end up on the final chain.&lt;&#x2F;p&gt;
&lt;p&gt;A simplistic but working strategy is to allow users to configure &quot;proposals&quot; on the signers (e.g. &quot;add 0x...&quot;, &quot;drop 0x...&quot;). The signing code can then pick a random proposal for every block it signs and inject it. This ensures that multiple concurrent proposals as well as reorgs get eventually noted on the chain.&lt;&#x2F;p&gt;
&lt;p&gt;This list may be expired after a certain number of blocks &#x2F; epochs, but it&#x27;s important to realize that &quot;seeing&quot; a proposal pass doesn&#x27;t mean it won&#x27;t get reorged, so it should not be immediately dropped when the proposal passes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; block represents a single block signed by a particular account, where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the account may or may not have cast a Clique vote.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  signer&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;     string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Account that signed this particular block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  voted&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Optional value if the signer voted on adding&#x2F;removing someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  auth&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;       bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Whether the vote was to authorize (or deauthorize)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  checkpoint&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; List of authorized signers if this is an epoch block&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Define the various voting scenarios to test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  epoch&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;   &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Number of blocks in an epoch (unset = 30000)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  signers&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Initial list of authorized signers in the genesis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  blocks&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Chain of signed blocks, potentially influencing auths&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  results&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Final list of authorized signers after all blocks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;  failure&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Failure if some block is invalid according to the rules&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&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;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Single signer, no votes cast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Single signer, voting to add two others (only accept first, second needs 2 votes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Two signers, voting to add three others (only accept first two, third needs 3 votes already)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Single signer, dropping itself (weird, but one less cornercase by explicitly allowing this)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Two signers, actually needing mutual consent to drop either of them (not fulfilled)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Two signers, actually needing mutual consent to drop either of them (fulfilled)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Three signers, two of them deciding to drop the third&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Four signers, consensus of two not being enough to drop anyone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Four signers, consensus of three already being enough to drop someone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizations are counted once per signer per target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorizing multiple accounts concurrently is permitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deauthorizations are counted once per signer per target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deauthorizing multiple accounts concurrently is permitted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Votes from deauthorized signers are discarded immediately (deauth votes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Votes from deauthorized signers are discarded immediately (auth votes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Cascading changes are not allowed, only the account being voted on may change&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Changes reaching consensus out of bounds (via a deauth) execute on touch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Changes reaching consensus out of bounds (via a deauth) may go out of consensus on first touch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure that pending votes don&amp;#39;t survive authorization status changes. This&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; corner case can only appear if a signer is quickly added, removed and then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; readded (or the inverse), while one of the original voters dropped. If a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; past vote is left cached in the system somewhere, this will interfere with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; the final signer outcome.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorize F, 3 votes needed&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 class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deauthorize F, 4 votes needed (leave A&amp;#39;s previous vote &amp;quot;unchanged&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 class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Almost authorize F, 2&#x2F;3 votes needed&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 class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deauthorize A, 3 votes needed&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 class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Finish authorizing F, 3&#x2F;3 votes needed&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&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;D&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;E&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Epoch transitions reset all votes to allow chain checkpointing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; checkpoint&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; voted&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    results&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;  }&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An unauthorized signer should not be able to sign blocks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    failure&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; errUnauthorizedSigner&lt;&#x2F;span&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;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; An authorized signer that signed recently should not be able to sign again&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    failure&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; errRecentlySigned&lt;&#x2F;span&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;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Recent signatures should not reset on checkpoint blocks imported in a batch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    epoch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-variable z-other&quot;&gt;    signers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;    blocks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;block&lt;&#x2F;span&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;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; checkpoint&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&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&gt;      {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;signer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-variable z-other&quot;&gt;    failure&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; errRecentlySigned&lt;&#x2F;span&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;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;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;A reference implementation is part of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;tree&#x2F;master&#x2F;consensus&#x2F;clique&quot;&gt;go-ethereum&lt;&#x2F;a&gt; and has been functioning as the consensus engine behind the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rinkeby.io&quot;&gt;Rinkeby&lt;&#x2F;a&gt; testnet since April, 2017.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Bitwise shifting instructions in EVM</title>
        <published>2017-02-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Paweł Bylica</name><uri>https://github.com/chfast</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/145/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/145/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:145"
            label="EIP-145" />
        

        
        

        
        <summary type="html">To Provide native bitwise shifting with cost on par with other arithmetic operations.</summary>
        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/145/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Native bitwise shifting instructions are introduced, which are more efficient processing wise on the host and are cheaper to use by a contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;EVM is lacking bitwise shifting operators, but supports other logical and arithmetic operators. Shift operations can be implemented via arithmetic operators, but that has a higher cost and requires more processing time from the host. Implementing &lt;code&gt;SHL&lt;&#x2F;code&gt; and &lt;code&gt;SHR&lt;&#x2F;code&gt; using arithmetic cost each 35 gas, while the proposed instructions take 3 gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The following instructions are introduced:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;0x1b-shl-shift-left&quot;&gt;&lt;code&gt;0x1b&lt;&#x2F;code&gt;: &lt;code&gt;SHL&lt;&#x2F;code&gt; (shift left)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;SHL&lt;&#x2F;code&gt; instruction (shift left) pops 2 values from the stack, first &lt;code&gt;arg1&lt;&#x2F;code&gt; and then &lt;code&gt;arg2&lt;&#x2F;code&gt;, and pushes on the stack &lt;code&gt;arg2&lt;&#x2F;code&gt; shifted to the left by &lt;code&gt;arg1&lt;&#x2F;code&gt; number of bits. The result is equal to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(arg2 * 2^arg1) mod 2^256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The value (&lt;code&gt;arg2&lt;&#x2F;code&gt;) is interpreted as an unsigned number.&lt;&#x2F;li&gt;
&lt;li&gt;The shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is interpreted as an unsigned number.&lt;&#x2F;li&gt;
&lt;li&gt;If the shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is greater or equal 256 the result is 0.&lt;&#x2F;li&gt;
&lt;li&gt;This is equivalent to &lt;code&gt;PUSH1 2 EXP MUL&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;0x1c-shr-logical-shift-right&quot;&gt;&lt;code&gt;0x1c&lt;&#x2F;code&gt;: &lt;code&gt;SHR&lt;&#x2F;code&gt; (logical shift right)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;SHR&lt;&#x2F;code&gt; instruction (logical shift right) pops 2 values from the stack, first &lt;code&gt;arg1&lt;&#x2F;code&gt; and then &lt;code&gt;arg2&lt;&#x2F;code&gt;, and pushes on the stack &lt;code&gt;arg2&lt;&#x2F;code&gt; shifted to the right by &lt;code&gt;arg1&lt;&#x2F;code&gt; number of bits with zero fill. The result is equal to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;floor(arg2 &#x2F; 2^arg1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The value (&lt;code&gt;arg2&lt;&#x2F;code&gt;) is interpreted as an unsigned number.&lt;&#x2F;li&gt;
&lt;li&gt;The shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is interpreted as an unsigned number.&lt;&#x2F;li&gt;
&lt;li&gt;If the shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is greater or equal 256 the result is 0.&lt;&#x2F;li&gt;
&lt;li&gt;This is equivalent to &lt;code&gt;PUSH1 2 EXP DIV&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;0x1d-sar-arithmetic-shift-right&quot;&gt;&lt;code&gt;0x1d&lt;&#x2F;code&gt;: &lt;code&gt;SAR&lt;&#x2F;code&gt; (arithmetic shift right)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;SAR&lt;&#x2F;code&gt; instruction (arithmetic shift right) pops 2 values from the stack, first &lt;code&gt;arg1&lt;&#x2F;code&gt; and then &lt;code&gt;arg2&lt;&#x2F;code&gt;, and pushes on the stack &lt;code&gt;arg2&lt;&#x2F;code&gt; shifted to the right by &lt;code&gt;arg1&lt;&#x2F;code&gt; number of bits with sign extension. The result is equal to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;floor(arg2 &#x2F; 2^arg1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The value (&lt;code&gt;arg2&lt;&#x2F;code&gt;) is interpreted as a signed number.&lt;&#x2F;li&gt;
&lt;li&gt;The shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is interpreted as an unsigned number.&lt;&#x2F;li&gt;
&lt;li&gt;If the shift amount (&lt;code&gt;arg1&lt;&#x2F;code&gt;) is greater or equal 256 the result is 0 if &lt;code&gt;arg2&lt;&#x2F;code&gt; is non-negative or -1 if &lt;code&gt;arg2&lt;&#x2F;code&gt; is negative.&lt;&#x2F;li&gt;
&lt;li&gt;This is &lt;strong&gt;not&lt;&#x2F;strong&gt; equivalent to &lt;code&gt;PUSH1 2 EXP SDIV&lt;&#x2F;code&gt;, since it rounds differently. See &lt;code&gt;SDIV(-1, 2) == 0&lt;&#x2F;code&gt;, while &lt;code&gt;SAR(-1, 1) == -1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The cost of the shift instructions is set at &lt;code&gt;verylow&lt;&#x2F;code&gt; tier (3 gas).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Instruction operands were chosen to fit the more natural use case of shifting a value already on the stack. This means the operand order is swapped compared to most arithmetic instructions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;The newly introduced instructions have no effect on bytecode created in the past.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;shl-shift-left&quot;&gt;&lt;code&gt;SHL&lt;&#x2F;code&gt; (shift left)&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHL&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;0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;shr-logical-shift-right&quot;&gt;&lt;code&gt;SHR&lt;&#x2F;code&gt; (logical shift right)&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x4000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;sar-arithmetic-shift-right&quot;&gt;&lt;code&gt;SAR&lt;&#x2F;code&gt; (arithmetic shift right)&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xc000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0101&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x01&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x4000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xfe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xf8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x000000000000000000000000000000000000000000000000000000000000007f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xfe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PUSH 0x0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAR&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;0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;Client support:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cpp-ethereum: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;cpp-ethereum&#x2F;pull&#x2F;4054&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Compiler support:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Solidity&#x2F;LLL: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;pull&#x2F;2541&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tests&quot;&gt;Tests&lt;&#x2F;h3&gt;
&lt;p&gt;Sources:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;tree&#x2F;develop&#x2F;src&#x2F;GeneralStateTestsFiller&#x2F;stShift&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Filled Tests:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;tree&#x2F;develop&#x2F;GeneralStateTests&#x2F;stShift&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;tests&#x2F;tree&#x2F;develop&#x2F;BlockchainTests&#x2F;GeneralStateTests&#x2F;stShift&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>&quot;New opcodes: RETURNDATASIZE and RETURNDATACOPY&quot;</title>
        <published>2017-02-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Christian Reitwiessner</name><email>chris@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/211/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/211/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:211"
            label="EIP-211" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/211/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and requires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already; after a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;Please see summary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;In some situations, it is vital for a function to be able to return data whose length cannot be anticipated before the call. In principle, this can be solved without alterations to the EVM, for example by splitting the call into two calls where the first is used to compute only the size. All of these mechanisms, though, are very expensive in at least some situations. A very useful example of such a worst-case situation is a generic forwarding contract; a contract that takes call data, potentially makes some checks and then forwards it as is to another contract. The return data should of course be transferred in a similar way to the original caller. Since the contract is generic and does not know about the contract it calls, there is no way to determine the size of the output without adapting the called contract accordingly or trying a logarithmic number of calls.&lt;&#x2F;p&gt;
&lt;p&gt;Compiler implementors are advised to reserve a zero-length area for return data if the size of the return data is unknown before the call and then use &lt;code&gt;RETURNDATACOPY&lt;&#x2F;code&gt; in conjunction with &lt;code&gt;RETURNDATASIZE&lt;&#x2F;code&gt; to actually retrieve the data.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this proposal also makes the EIP that proposes to allow to return data in case of an intentional state reversion (&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;140&#x2F;&quot;&gt;EIP-140&lt;&#x2F;a&gt;) much more useful. Since the size of the failure data might be larger than the regular return data (or even unknown), it is possible to retrieve the failure data after the CALL opcode has signalled a failure, even if the regular output area is not large enough to hold the data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt;, add two new opcodes and amend the semantics of any opcode that creates a new call frame (like &lt;code&gt;CALL&lt;&#x2F;code&gt;, &lt;code&gt;CREATE&lt;&#x2F;code&gt;, &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt;, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;140&#x2F;&quot;&gt;EIP-140&lt;&#x2F;a&gt;) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty.&lt;&#x2F;p&gt;
&lt;p&gt;As an optimization, it is possible to share the return data buffer across call frames because at most one will be non-empty at any time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;RETURNDATASIZE&lt;&#x2F;code&gt;: &lt;code&gt;0x3d&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Pushes the size of the return data buffer onto the stack.
Gas costs: 2 (same as &lt;code&gt;CALLDATASIZE&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;RETURNDATACOPY&lt;&#x2F;code&gt;: &lt;code&gt;0x3e&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This opcode has similar semantics to &lt;code&gt;CALLDATACOPY&lt;&#x2F;code&gt;, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure; i.e. if &lt;code&gt;start + length&lt;&#x2F;code&gt; overflows or results in a value larger than &lt;code&gt;RETURNDATASIZE&lt;&#x2F;code&gt;, the current call stops in an out-of-gas condition. In particular, reading 0 bytes from the end of the buffer will read 0 bytes; reading 0 bytes from one-byte out of the buffer causes an exception.&lt;&#x2F;p&gt;
&lt;p&gt;Gas costs: &lt;code&gt;3 + 3 * ceil(amount &#x2F; 32)&lt;&#x2F;code&gt; (same as &lt;code&gt;CALLDATACOPY&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;Other solutions that would allow returning dynamic data were considered, but they all had to deduct the gas from the call opcode and thus were both complicated to implement and specify (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;8&quot;&gt;5&#x2F;8&lt;&#x2F;a&gt;). Since this proposal is very similar to the way calldata is handled, it fits nicely into the concept. Furthermore, the eWASM architecture already handles return data in exactly the same way.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the EVM implementation needs to keep the return data until the next call or the return from the current call. Since this resource was already paid for as part of the memory of the callee, it should not be a problem. Implementations may either choose to keep the full memory of the callee alive until the next call or copy only the return data to a special memory area.&lt;&#x2F;p&gt;
&lt;p&gt;Keeping the memory of the callee until the next call-like opcode does not increase the peak memory usage in the following sense; any memory allocation in the caller&#x27;s frame that happens after the return from the call can be moved before the call without a change in gas costs, but will add this allocation to the peak allocation.&lt;&#x2F;p&gt;
&lt;p&gt;The number values of the opcodes were allocated in the same nibble block that also contains &lt;code&gt;CALLDATASIZE&lt;&#x2F;code&gt; and &lt;code&gt;CALLDATACOPY&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal introduces two new opcodes and stays fully backwards compatible apart from that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>New opcode STATICCALL</title>
        <published>2017-02-13T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><email>vitalik@ethereum.org</email>
	</author>
	
	<author>
		<name>Christian Reitwiessner</name><email>chris@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/214/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/214/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:214"
            label="EIP-214" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/214/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;To increase smart contract security, this proposal adds a new opcode that can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal adds a new opcode that can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present). Any opcode that attempts to perform such a modification (see below for details) will result in an exception instead of performing the modification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, there is no restriction about what a called contract can do, as long as the computation can be performed with the amount of gas provided. This poses certain difficulties about smart contract engineers; after a regular call, unless you know the called contract, you cannot make any assumptions about the state of the contracts. Furthermore, because you cannot know the order of transactions before they are confirmed by miners, not even an outside observer can be sure about that in all cases.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP adds a way to call other contracts and restrict what they can do in the simplest way. It can be safely assumed that the state of all accounts is the same before and after a static call.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;Introduce a new &lt;code&gt;STATIC&lt;&#x2F;code&gt; flag to the virtual machine. This flag is set to &lt;code&gt;false&lt;&#x2F;code&gt; initially. Its value is always copied to sub-calls with an exception for the new opcode below.&lt;&#x2F;p&gt;
&lt;p&gt;Opcode: &lt;code&gt;0xfa&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;STATICCALL&lt;&#x2F;code&gt; functions equivalently to a &lt;code&gt;CALL&lt;&#x2F;code&gt;, except it takes only 6 arguments (the &quot;value&quot; argument is not included and taken to be zero), and calls the child with the &lt;code&gt;STATIC&lt;&#x2F;code&gt; flag set to &lt;code&gt;true&lt;&#x2F;code&gt; for the execution of the child. Once this call returns, the flag is reset to its value before the call.&lt;&#x2F;p&gt;
&lt;p&gt;Any attempts to make state-changing operations inside an execution instance with &lt;code&gt;STATIC&lt;&#x2F;code&gt; set to &lt;code&gt;true&lt;&#x2F;code&gt; will instead throw an exception. These operations include &lt;code&gt;CREATE&lt;&#x2F;code&gt;, &lt;code&gt;CREATE2&lt;&#x2F;code&gt;, &lt;code&gt;LOG0&lt;&#x2F;code&gt;, &lt;code&gt;LOG1&lt;&#x2F;code&gt;, &lt;code&gt;LOG2&lt;&#x2F;code&gt;, &lt;code&gt;LOG3&lt;&#x2F;code&gt;, &lt;code&gt;LOG4&lt;&#x2F;code&gt;, &lt;code&gt;SSTORE&lt;&#x2F;code&gt;, and &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;. They also include &lt;code&gt;CALL&lt;&#x2F;code&gt; with a non-zero value. As an exception, &lt;code&gt;CALLCODE&lt;&#x2F;code&gt; is not considered state-changing, even with a non-zero value.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;This allows contracts to make calls that are clearly non-state-changing, reassuring developers and reviewers that re-entrancy bugs or other problems cannot possibly arise from that particular call; it is a pure function that returns an output and does nothing else. This may also make purely functional HLLs easier to implement.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This proposal adds a new opcode but does not modify the behaviour of other opcodes and thus is backwards compatible for old contracts that do not use the new opcode and are not called via the new opcode.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;To be written.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Designated invalid EVM instruction</title>
        <published>2017-02-09T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/141/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/141/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:141"
            label="EIP-141" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/141/">&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;An instruction is designated to remain as an invalid instruction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;The invalid instruction can be used as a distinct reason to abort execution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;The opcode &lt;code&gt;0xfe&lt;&#x2F;code&gt; is the &lt;code&gt;INVALID&lt;&#x2F;code&gt; instruction. It can be used to abort the execution (i.e. duplicates as an &lt;code&gt;ABORT&lt;&#x2F;code&gt; instruction).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This instruction was never used and therefore has no effect on past contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>REVERT instruction</title>
        <published>2017-02-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Alex Beregszaszi</name><uri>https://github.com/axic</uri>
	</author>
	
	<author>
		<name>Nikolai Mushegian</name><email>nikolai@nexusdev.us</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/140/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/140/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:140"
            label="EIP-140" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/140/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;REVERT&lt;&#x2F;code&gt; instruction provides a way to stop execution and revert state changes, without consuming all provided gas and with the ability to return a reason.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;REVERT&lt;&#x2F;code&gt; instruction will stop execution, roll back all state changes done so far and provide a pointer to a memory section, which can be interpreted as an error code or message. While doing so, it will not consume all the remaining gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Currently this is not possible. There are two practical ways to revert a transaction from within a contract: running out of gas or executing an invalid instruction. Both of these options will consume all remaining gas. Additionally, reverting an EVM execution means that all changes, including LOGs, are lost and there is no way to convey a reason for aborting an EVM execution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;On blocks with &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt;, the &lt;code&gt;REVERT&lt;&#x2F;code&gt; instruction is introduced at &lt;code&gt;0xfd&lt;&#x2F;code&gt;. It expects two stack items, the top item is the &lt;code&gt;memory_offset&lt;&#x2F;code&gt; followed by &lt;code&gt;memory_length&lt;&#x2F;code&gt;. It does not produce any stack elements because it stops execution.&lt;&#x2F;p&gt;
&lt;p&gt;The semantics of &lt;code&gt;REVERT&lt;&#x2F;code&gt; with respect to memory and memory cost are identical to those of &lt;code&gt;RETURN&lt;&#x2F;code&gt;. The sequence of bytes given by &lt;code&gt;memory_offset&lt;&#x2F;code&gt; and &lt;code&gt;memory_length&lt;&#x2F;code&gt; is called &quot;error message&quot; in the following.&lt;&#x2F;p&gt;
&lt;p&gt;The effect of &lt;code&gt;REVERT&lt;&#x2F;code&gt; is that execution is aborted, considered as failed, and state changes are rolled back. The error message will be available to the caller in the returndata buffer and will also be copied to the output area, i.e. it is handled in the same way as the regular return data is handled.&lt;&#x2F;p&gt;
&lt;p&gt;The cost of the &lt;code&gt;REVERT&lt;&#x2F;code&gt; instruction equals to that of the &lt;code&gt;RETURN&lt;&#x2F;code&gt; instruction, i.e. the rollback itself does not consume all gas, the contract only has to pay for memory.&lt;&#x2F;p&gt;
&lt;p&gt;In case there is not enough gas left to cover the cost of &lt;code&gt;REVERT&lt;&#x2F;code&gt; or there is a stack underflow, the effect of the &lt;code&gt;REVERT&lt;&#x2F;code&gt; instruction will equal to that of a regular out of gas exception, i.e. it will consume all gas.&lt;&#x2F;p&gt;
&lt;p&gt;In the same way as all other failures, the calling opcode returns &lt;code&gt;0&lt;&#x2F;code&gt; on the stack following a &lt;code&gt;REVERT&lt;&#x2F;code&gt; opcode in the callee.&lt;&#x2F;p&gt;
&lt;p&gt;In case &lt;code&gt;REVERT&lt;&#x2F;code&gt; is used in the context of a &lt;code&gt;CREATE&lt;&#x2F;code&gt; or &lt;code&gt;CREATE2&lt;&#x2F;code&gt; call, no code is deployed, &lt;code&gt;0&lt;&#x2F;code&gt; is put on the stack and the error message is available in the returndata buffer.&lt;&#x2F;p&gt;
&lt;p&gt;The content of the optionally provided memory section is not defined by this EIP, but is a candidate for another Informational EIP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;This change has no effect on contracts created in the past unless they contain &lt;code&gt;0xfd&lt;&#x2F;code&gt; as an instruction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6c726576657274656420646174616000557f726576657274206d657373616765000000000000000000000000000000000000600052600e6000fd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;should:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;return &lt;code&gt;0x726576657274206d657373616765&lt;&#x2F;code&gt; as &lt;code&gt;REVERT&lt;&#x2F;code&gt; data,&lt;&#x2F;li&gt;
&lt;li&gt;the storage at key &lt;code&gt;0x0&lt;&#x2F;code&gt; should be left as unset and&lt;&#x2F;li&gt;
&lt;li&gt;use 20024 gas in total.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128</title>
        <published>2017-02-06T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><email>vitalik@ethereum.org</email>
	</author>
	
	<author>
		<name>Christian Reitwiessner</name><email>chris@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/197/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/197/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:197"
            label="EIP-197" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/197/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Precompiled contracts for elliptic curve pairing operations are required in order to perform zkSNARK verification within the block gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;196&#x2F;&quot;&gt;EIP-196&lt;&#x2F;a&gt; to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive
to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced.&lt;&#x2F;p&gt;
&lt;p&gt;Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork.&lt;&#x2F;p&gt;
&lt;p&gt;Pairing functions can be used to perform a limited form of multiplicatively homomorphic operations, which are necessary for current zkSNARKs. This precompile can be used to run such computations within the block gas limit. This precompiled contract only specifies a certain check, and not an evaluation of a pairing function. The reason is that the codomain of a pairing function is a rather complex field which could provide encoding problems and all known uses of pairing function in zkSNARKs only require the specified check.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;For blocks where &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt;, add a precompiled contracts for a bilinear function on groups on the elliptic curve &quot;alt_bn128&quot;. We will define the precompiled contract in terms of a discrete logarithm. The discrete logarithm is of course assumed to be hard to compute, but we will give an equivalent specification that makes use of elliptic curve pairing functions which can be efficiently computed below.&lt;&#x2F;p&gt;
&lt;p&gt;Address: 0x8&lt;&#x2F;p&gt;
&lt;p&gt;For a cyclic group &lt;code&gt;G&lt;&#x2F;code&gt; (written additively) of prime order &lt;code&gt;q&lt;&#x2F;code&gt; let &lt;code&gt;log_P: G -&amp;gt; F_q&lt;&#x2F;code&gt; be the discrete logarithm on this group with respect to a generator &lt;code&gt;P&lt;&#x2F;code&gt;, i.e. &lt;code&gt;log_P(x)&lt;&#x2F;code&gt; is the smallest non-negative integer &lt;code&gt;n&lt;&#x2F;code&gt; such that &lt;code&gt;n * P = x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The precompiled contract is defined as follows, where the two groups &lt;code&gt;G_1&lt;&#x2F;code&gt; and &lt;code&gt;G_2&lt;&#x2F;code&gt; are defined by their generators &lt;code&gt;P_1&lt;&#x2F;code&gt; and &lt;code&gt;P_2&lt;&#x2F;code&gt; below. Both generators have the same prime order &lt;code&gt;q&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Output: If the length of the input is incorrect or any of the inputs are not elements of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        the respective group or are not encoded correctly, the call fails.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Otherwise, return one if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (in F_q) and zero else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that &lt;code&gt;k&lt;&#x2F;code&gt; is determined from the length of the input. Following the section on the encoding below,
&lt;code&gt;k&lt;&#x2F;code&gt; is the length of the input divided by &lt;code&gt;192&lt;&#x2F;code&gt;. If the input length is not a multiple of &lt;code&gt;192&lt;&#x2F;code&gt;,
the call fails. Empty input is valid and results in returning one.&lt;&#x2F;p&gt;
&lt;p&gt;In order to check that an input is an element of &lt;code&gt;G_1&lt;&#x2F;code&gt;, verifying the encoding of the coordinates and checking that they satisfy the curve equation (or is the encoding of infinity) is sufficient. For &lt;code&gt;G_2&lt;&#x2F;code&gt;, in addition to that, the order of the element has to be checked to be equal to the group order &lt;code&gt;q = 21888242871839275222246405745257275088548364400416034343698204186575808495617&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-of-the-groups&quot;&gt;Definition of the groups&lt;&#x2F;h3&gt;
&lt;p&gt;The groups &lt;code&gt;G_1&lt;&#x2F;code&gt; and &lt;code&gt;G_2&lt;&#x2F;code&gt; are cyclic groups of prime order &lt;code&gt;q = 21888242871839275222246405745257275088548364400416034343698204186575808495617&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The group &lt;code&gt;G_1&lt;&#x2F;code&gt; is defined on the curve &lt;code&gt;Y^2 = X^3 + 3&lt;&#x2F;code&gt; over the field &lt;code&gt;F_p&lt;&#x2F;code&gt; with &lt;code&gt;p = 21888242871839275222246405745257275088696311157297823662689037894645226208583&lt;&#x2F;code&gt; with generator &lt;code&gt;P1 = (1, 2)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The group &lt;code&gt;G_2&lt;&#x2F;code&gt; is defined on the curve &lt;code&gt;Y^2 = X^3 + 3&#x2F;(i+9)&lt;&#x2F;code&gt; over a different field &lt;code&gt;F_p^2 = F_p[i] &#x2F; (i^2 + 1)&lt;&#x2F;code&gt; (p is the same as above) with generator&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;P2 = (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  11559732032986387107991004021392285783925812861821192530917403151452391805634 * i +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  10857046999023057135944570762232829481370756359578518086990519993285655852781,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  4082367875863433681332203403145435568316851327593401208105741076214120093531 * i +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  8495653923123431417604973247489272438418190587263600148770280649306958101930&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;Note that &lt;code&gt;G_2&lt;&#x2F;code&gt; is the only group of order &lt;code&gt;q&lt;&#x2F;code&gt; of that elliptic curve over the field &lt;code&gt;F_p^2&lt;&#x2F;code&gt;. Any other generator of order &lt;code&gt;q&lt;&#x2F;code&gt; instead of &lt;code&gt;P2&lt;&#x2F;code&gt; would define the same &lt;code&gt;G_2&lt;&#x2F;code&gt;. However, the concrete value of &lt;code&gt;P2&lt;&#x2F;code&gt; is useful for skeptical readers who doubt the existence of a group of order &lt;code&gt;q&lt;&#x2F;code&gt;. They can be instructed to compare the concrete values of &lt;code&gt;q * P2&lt;&#x2F;code&gt; and &lt;code&gt;P2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;encoding&quot;&gt;Encoding&lt;&#x2F;h3&gt;
&lt;p&gt;Elements of &lt;code&gt;F_p&lt;&#x2F;code&gt; are encoded as 32 byte big-endian numbers. An encoding value of &lt;code&gt;p&lt;&#x2F;code&gt; or larger is invalid.&lt;&#x2F;p&gt;
&lt;p&gt;Elements &lt;code&gt;a * i + b&lt;&#x2F;code&gt; of &lt;code&gt;F_p^2&lt;&#x2F;code&gt; are encoded as two elements of &lt;code&gt;F_p&lt;&#x2F;code&gt;, &lt;code&gt;(a, b)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Elliptic curve points are encoded as a Jacobian pair &lt;code&gt;(X, Y)&lt;&#x2F;code&gt; where the point at infinity is encoded as &lt;code&gt;(0, 0)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the number &lt;code&gt;k&lt;&#x2F;code&gt; is derived from the input length.&lt;&#x2F;p&gt;
&lt;p&gt;The length of the returned data is always exactly 32 bytes and encoded as a 32 byte big-endian number.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-costs&quot;&gt;Gas costs&lt;&#x2F;h3&gt;
&lt;p&gt;The gas costs of the precompiled contract are &lt;code&gt;80 000 * k + 100 000&lt;&#x2F;code&gt;, where &lt;code&gt;k&lt;&#x2F;code&gt; is the number of
points or, equivalently, the length of the input divided by 192.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The specific curve &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts.&lt;&#x2F;p&gt;
&lt;p&gt;The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification; the gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve or does not admit an efficient pairing implementation.&lt;&#x2F;p&gt;
&lt;p&gt;A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate).&lt;&#x2F;p&gt;
&lt;p&gt;The encoding of field elements in &lt;code&gt;F_p^2&lt;&#x2F;code&gt; was chosen in this order to be in line with the big endian encoding of the elements themselves.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As with the introduction of any precompiled contract, contracts that already use the given addresses will change their semantics. Because of that, the addresses are taken from the &quot;reserved range&quot; below 256.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;To be written.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The precompiled contract can be implemented using elliptic curve pairing functions, more specifically, an optimal ate pairing on the alt_bn128 curve, which can be implemented efficiently. In order to see that, first note that a pairing function &lt;code&gt;e: G_1 x G_2 -&amp;gt; G_T&lt;&#x2F;code&gt; fulfills the following properties (&lt;code&gt;G_1&lt;&#x2F;code&gt; and &lt;code&gt;G_2&lt;&#x2F;code&gt; are written additively, &lt;code&gt;G_T&lt;&#x2F;code&gt; is written multiplicatively):&lt;&#x2F;p&gt;
&lt;p&gt;(1) &lt;code&gt;e(m * P1, n * P2) = e(P1, P2)^(m * n)&lt;&#x2F;code&gt;
(2) &lt;code&gt;e&lt;&#x2F;code&gt; is non-degenerate&lt;&#x2F;p&gt;
&lt;p&gt;Now observe that&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 (in F_q)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;if and only if&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e(P1, P2)^(log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk)) = 1 (in G_T)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Furthermore, the left hand side of this equation is equal to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e(log_P1(a1) * P1, log_P2(b1) * P2) * ... * e(log_P1(ak) * P1, log_P2(bk) * P2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;= e(a1, b1) * ... * e(ak, bk)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And thus, the precompiled contract can be implemented by verifying that
&lt;code&gt;e(a1, b1) * ... * e(ak, bk) = 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Implementations are available here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;scipr-lab&#x2F;libff&#x2F;blob&#x2F;master&#x2F;libff&#x2F;algebra&#x2F;curves&#x2F;alt_bn128&#x2F;alt_bn128_g1.hpp&quot;&gt;libff&lt;&#x2F;a&gt; (C++)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zcash&#x2F;bn&#x2F;blob&#x2F;master&#x2F;src&#x2F;groups&#x2F;mod.rs&quot;&gt;bn&lt;&#x2F;a&gt; (Rust)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;py_pairing&#x2F;blob&#x2F;master&#x2F;py_ecc&#x2F;bn128&#x2F;bn128_pairing.py&quot;&gt;Python&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128</title>
        <published>2017-02-02T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Christian Reitwiessner</name><email>chris@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/196/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/196/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:196"
            label="EIP-196" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/196/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Precompiled contracts for elliptic curve operations are required in order to perform zkSNARK verification within the block gas limit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;197&#x2F;&quot;&gt;EIP-197&lt;&#x2F;a&gt; to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive
to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced.&lt;&#x2F;p&gt;
&lt;p&gt;Note that while fixing these parameters might look like limiting the use-cases for zkSNARKs, the primitives are so basic that they can be combined in ways that are flexible enough so that it should even be possible to allow future advances in zkSNARK research without the need for a further hard fork.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt;, add precompiled contracts for point addition (ADD)  and scalar multiplication (MUL) on the elliptic curve &quot;alt_bn128&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Address of ADD: 0x6
Address for MUL: 0x7&lt;&#x2F;p&gt;
&lt;p&gt;The curve is defined by:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Y^2 = X^3 + 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;over the field F_p with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p = 21888242871839275222246405745257275088696311157297823662689037894645226208583&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;encoding&quot;&gt;Encoding&lt;&#x2F;h3&gt;
&lt;p&gt;Field elements and scalars are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements &lt;code&gt;(x, y)&lt;&#x2F;code&gt;, where the point at infinity is encoded as &lt;code&gt;(0, 0)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Tuples of objects are encoded as their concatenation.&lt;&#x2F;p&gt;
&lt;p&gt;For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the &lt;code&gt;CALLDATALOAD&lt;&#x2F;code&gt; opcode). If the input is longer than expected, surplus bytes at the end are ignored.&lt;&#x2F;p&gt;
&lt;p&gt;The length of the returned data is always as specified (i.e. it is not &quot;unpadded&quot;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exact-semantics&quot;&gt;Exact semantics&lt;&#x2F;h3&gt;
&lt;p&gt;Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates) is equal or larger than the field modulus p, the contract fails. The scalar can be any number between &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;2**256-1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;add&quot;&gt;ADD&lt;&#x2F;h4&gt;
&lt;p&gt;Input: two curve points &lt;code&gt;(x, y)&lt;&#x2F;code&gt;.
Output: curve point &lt;code&gt;x + y&lt;&#x2F;code&gt;, where &lt;code&gt;+&lt;&#x2F;code&gt; is point addition on the elliptic curve &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; specified above.
Fails on invalid input and consumes all gas provided.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mul&quot;&gt;MUL&lt;&#x2F;h4&gt;
&lt;p&gt;Input: curve point and scalar &lt;code&gt;(x, s)&lt;&#x2F;code&gt;.
Output: curve point &lt;code&gt;s * x&lt;&#x2F;code&gt;, where &lt;code&gt;*&lt;&#x2F;code&gt; is the scalar multiplication on the elliptic curve &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; specified above.
Fails on invalid input and consumes all gas.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gas-costs&quot;&gt;Gas costs&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Gas cost for &lt;code&gt;ECADD&lt;&#x2F;code&gt;: 500&lt;&#x2F;li&gt;
&lt;li&gt;Gas cost for &lt;code&gt;ECMUL&lt;&#x2F;code&gt;: 40000&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;The specific curve &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts.&lt;&#x2F;p&gt;
&lt;p&gt;The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification: The gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve.&lt;&#x2F;p&gt;
&lt;p&gt;A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;As with the introduction of any precompiled contract, contracts that already use the given addresses will change their semantics. Because of that, the addresses are taken from the &quot;reserved range&quot; below 256.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;p&gt;Inputs to test:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Curve points which would be valid if the numbers were taken mod p (should fail).&lt;&#x2F;li&gt;
&lt;li&gt;Both contracts should succeed on empty input.&lt;&#x2F;li&gt;
&lt;li&gt;Truncated input that results in a valid curve point.&lt;&#x2F;li&gt;
&lt;li&gt;Points not on curve (but valid otherwise).&lt;&#x2F;li&gt;
&lt;li&gt;Multiply point with scalar that lies between the order of the group and the field (should succeed).&lt;&#x2F;li&gt;
&lt;li&gt;Multiply point with scalar that is larger than the field order (should succeed).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Implementation of these primitives are available here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;scipr-lab&#x2F;libff&#x2F;blob&#x2F;master&#x2F;libff&#x2F;algebra&#x2F;curves&#x2F;alt_bn128&#x2F;alt_bn128_g1.cpp&quot;&gt;libff&lt;&#x2F;a&gt; (C++)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zcash&#x2F;bn&#x2F;blob&#x2F;master&#x2F;src&#x2F;groups&#x2F;mod.rs&quot;&gt;bn&lt;&#x2F;a&gt; (Rust)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In both codebases, a specific group on the curve alt_bn128 is used and is called G1.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;py_pairing&#x2F;blob&#x2F;master&#x2F;py_ecc&#x2F;bn128&#x2F;bn128_curve.py&quot;&gt;Python&lt;&#x2F;a&gt; - probably most self-contained and best readable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Big integer modular exponentiation</title>
        <published>2017-01-30T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/198/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/198/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:198"
            label="EIP-198" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/198/">&lt;h1 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GQUADDIVISOR: 20&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;At address 0x00......05, add a precompile that expects input in the following format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;length_of_BASE&amp;gt; &amp;lt;length_of_EXPONENT&amp;gt; &amp;lt;length_of_MODULUS&amp;gt; &amp;lt;BASE&amp;gt; &amp;lt;EXPONENT&amp;gt; &amp;lt;MODULUS&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where every length is a 32-byte left-padded integer representing the number of bytes to be taken up by the next value. Call data is assumed to be infinitely right-padded with zero bytes, and excess data is ignored. Consumes &lt;code&gt;floor(mult_complexity(max(length_of_MODULUS, length_of_BASE)) * max(ADJUSTED_EXPONENT_LENGTH, 1) &#x2F; GQUADDIVISOR)&lt;&#x2F;code&gt; gas, and if there is enough gas, returns an output &lt;code&gt;(BASE**EXPONENT) % MODULUS&lt;&#x2F;code&gt; as a byte array with the same length as the modulus.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ADJUSTED_EXPONENT_LENGTH&lt;&#x2F;code&gt; is defined as follows.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;length_of_EXPONENT &amp;lt;= 32&lt;&#x2F;code&gt;, and all bits in &lt;code&gt;EXPONENT&lt;&#x2F;code&gt; are 0, return 0&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;length_of_EXPONENT &amp;lt;= 32&lt;&#x2F;code&gt;, then return the index of the highest bit in &lt;code&gt;EXPONENT&lt;&#x2F;code&gt; (eg. 1 -&amp;gt; 0, 2 -&amp;gt; 1, 3 -&amp;gt; 1, 255 -&amp;gt; 7, 256 -&amp;gt; 8).&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;length_of_EXPONENT &amp;gt; 32&lt;&#x2F;code&gt;, then return &lt;code&gt;8 * (length_of_EXPONENT - 32)&lt;&#x2F;code&gt; plus the index of the highest bit in the first 32 bytes of &lt;code&gt;EXPONENT&lt;&#x2F;code&gt; (eg. if &lt;code&gt;EXPONENT = \x00\x00\x01\x00.....\x00&lt;&#x2F;code&gt;, with one hundred bytes, then the result is 8 * (100 - 32) + 253 = 797). If all of the first 32 bytes of &lt;code&gt;EXPONENT&lt;&#x2F;code&gt; are zero, return exactly &lt;code&gt;8 * (length_of_EXPONENT - 32)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;mult_complexity&lt;&#x2F;code&gt; is a function intended to approximate the difficulty of Karatsuba multiplication (used in all major bigint libraries) and is defined as follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def mult_complexity(x):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if x &amp;lt;= 64: return x ** 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elif x &amp;lt;= 1024: return x ** 2 &#x2F;&#x2F; 4 + 96 * x - 3072&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    else: return x ** 2 &#x2F;&#x2F; 16 + 480 * x - 199680&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example, the input data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Represents the exponent &lt;code&gt;3**(2**256 - 2**32 - 978) % (2**256 - 2**32 - 977)&lt;&#x2F;code&gt;. By Fermat&#x27;s little theorem, this equals 1, so the result is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Returned as 32 bytes because the modulus length was 32 bytes. The &lt;code&gt;ADJUSTED_EXPONENT_LENGTH&lt;&#x2F;code&gt; would be 255, and the gas cost would be &lt;code&gt;mult_complexity(32) * 255 &#x2F; 20 = 13056&lt;&#x2F;code&gt; gas (note that this is ~8 times the cost of using the EXP opcode to compute a 32-byte exponent). A 4096-bit RSA exponentiation would cost &lt;code&gt;mult_complexity(512) * 4095 &#x2F; 100 = 22853376&lt;&#x2F;code&gt; gas in the worst case, though RSA verification in practice usually uses an exponent of 3 or 65537, which would reduce the gas consumption to 5580 or 89292, respectively.&lt;&#x2F;p&gt;
&lt;p&gt;This input data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Would be parsed as a base of 0, exponent of &lt;code&gt;2**256 - 2**32 - 978&lt;&#x2F;code&gt; and modulus of &lt;code&gt;2**256 - 2**32 - 977&lt;&#x2F;code&gt;, and so would return 0. Notice how if the length_of_BASE is 0, then it does not interpret &lt;em&gt;any&lt;&#x2F;em&gt; data as the base, instead immediately interpreting the next 32 bytes as EXPONENT.&lt;&#x2F;p&gt;
&lt;p&gt;This input data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Would parse a base length of 0, an exponent length of 32, and a modulus length of &lt;code&gt;2**256 - 1&lt;&#x2F;code&gt;, where the base is empty, the exponent is &lt;code&gt;2**256 - 2&lt;&#x2F;code&gt; and the modulus is &lt;code&gt;(2**256 - 3) * 256**(2**256 - 33)&lt;&#x2F;code&gt; (yes, that&#x27;s a really big number). It would then immediately fail, as it&#x27;s not possible to provide enough gas to make that computation.&lt;&#x2F;p&gt;
&lt;p&gt;This input data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;07&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Would parse as a base of 3, an exponent of 65535, and a modulus of &lt;code&gt;2**255&lt;&#x2F;code&gt;, and it would ignore the remaining 0x07 byte.&lt;&#x2F;p&gt;
&lt;p&gt;This input data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000002&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Would also parse as a base of 3, an exponent of 65535 and a modulus of &lt;code&gt;2**255&lt;&#x2F;code&gt;, as it attempts to grab 32 bytes for the modulus starting from 0x80 - but there is no further data, so it right-pads it with 31 zero bytes.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h1&gt;
&lt;p&gt;This allows for efficient RSA verification inside of the EVM, as well as other forms of number theory-based cryptography. Note that adding precompiles for addition and subtraction is not required, as the in-EVM algorithm is efficient enough, and multiplication can be done through this precompile via &lt;code&gt;a * b = ((a + b)**2 - (a - b)**2) &#x2F; 4&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The bit-based exponent calculation is done specifically to fairly charge for the often-used exponents of 2 (for multiplication) and 3 and 65537 (for RSA verification).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h1&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum Smart Contract Packaging Standard</title>
        <published>2017-01-10T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Piper Merriam</name><uri>https://github.com/pipermerriam</uri>
	</author>
	
	<author>
		<name>Tim Coulter</name><uri>https://github.com/tcoulter</uri>
	</author>
	
	<author>
		<name>Denis Erfurt</name><uri>https://github.com/mhhf</uri>
	</author>
	
	<author>
		<name>RJ Catalano</name><uri>https://github.com/VoR0220</uri>
	</author>
	
	<author>
		<name>Iuri Matias</name><uri>https://github.com/iurimatias</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/190/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/190/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:190"
            label="ERC-190" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/190/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This ERC proposes a specification for Ethereum smart contract packages.&lt;&#x2F;p&gt;
&lt;p&gt;The specification was collaboratively developed by the following Ethereum development framework maintainers.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Tim Coulter (Truffle)&lt;&#x2F;li&gt;
&lt;li&gt;Denis Erfurt (Dapple)&lt;&#x2F;li&gt;
&lt;li&gt;Piper Merriam (Populus)&lt;&#x2F;li&gt;
&lt;li&gt;RJ Catalano (Eris PM)&lt;&#x2F;li&gt;
&lt;li&gt;Iuri Matias (Embark)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;Packaging is a core piece of modern software development which is missing from the Ethereum ecosystem.  The lack of packaging limits the ability for developers to reuse code which negatively affects productivity and security.&lt;&#x2F;p&gt;
&lt;p&gt;A key example of this is the ERC20 standard.  There are a few well audited reusable token contracts available but most developers end up writing their own because of the difficulty in finding and reusing existing code.&lt;&#x2F;p&gt;
&lt;p&gt;A packaging standard should have the following positive effects on the ecosystem:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Greater overall productivity caused by the ability to reuse existing code.&lt;&#x2F;li&gt;
&lt;li&gt;Increased security caused by the ability to reuse existing well audited implementations of common patterns (ERC20, crowdfunding, etc).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Smart contract packaging should also have a direct positive effect on the end user.  Wallet software will be able to consume a released package and generate an interface for interacting with any deployed contracts included within that package.  With the advent of &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;ENS&lt;&#x2F;a&gt; all of the pieces will be in place for a wallet to take a human readable name and present the user with an interface for interacting with the underlying application.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;The full specification for this standard is maintained separately in the repository &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&quot;&gt;epm&#x2F;epm-spec&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP refers to the &lt;code&gt;1.0.0&lt;&#x2F;code&gt; version of the specification: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;tree&#x2F;v1.0.0&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;tree&#x2F;v1.0.0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The specification contains details for a single document referred to as a &lt;em&gt;&quot;Release Lockfile&quot;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Release Lockfile Specification: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;blob&#x2F;v1.0.0&#x2F;release-lockfile.spec.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;blob&#x2F;v1.0.0&#x2F;release-lockfile.spec.md&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;JSON Schema for Release Lockfile: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;blob&#x2F;v1.0.0&#x2F;spec&#x2F;release-lockfile.spec.json&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;blob&#x2F;v1.0.0&#x2F;spec&#x2F;release-lockfile.spec.json&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;These documents have not been inlined into this ERC to ensure that there is a single source of truth for the specification.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h1 id=&quot;use-cases&quot;&gt;Use Cases&lt;&#x2F;h1&gt;
&lt;p&gt;This specification covers the following types of smart contract packages.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Packages with contracts intended to be used as base contract such as the common &lt;code&gt;owned&lt;&#x2F;code&gt; pattern.&lt;&#x2F;li&gt;
&lt;li&gt;Packages with contracts that are ready to use as-is such as an ERC20 token contract.&lt;&#x2F;li&gt;
&lt;li&gt;Packages with deployed contracts such as libraries or services.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Full explanations and examples of these use cases can be found in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethpm&#x2F;epm-spec&#x2F;blob&#x2F;v1.0.0&#x2F;README.md#use-cases&quot;&gt;&lt;code&gt;README.md&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; from the &lt;code&gt;epm&#x2F;epm-spec&lt;&#x2F;code&gt; repository.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;package-managers&quot;&gt;Package Managers&lt;&#x2F;h1&gt;
&lt;p&gt;The &lt;em&gt;Release Lockfile&lt;&#x2F;em&gt; is intended for consumption by package management software.  Specific care was made to ensure that all of the following functionality can be implemented by package managers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deterministic-builds&quot;&gt;Deterministic builds&lt;&#x2F;h2&gt;
&lt;p&gt;Ensures that a package will always resolve to the same set of dependencies and source files.  Both source files and dependencies are content addressed to ensure that the referenced resources cannot change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bytecode-verification&quot;&gt;Bytecode verification&lt;&#x2F;h2&gt;
&lt;p&gt;Contains the appropriate information for a package manager to inspect a deployed contract and verify that its bytecode matches the bytecode that results from compilation and linking of the package source code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multi-chain-deploys&quot;&gt;Multi-chain deploys&lt;&#x2F;h2&gt;
&lt;p&gt;Supports deployments across multiple chains, allowing a package to define addresses on both the public mainnet and testnet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trusted-packages&quot;&gt;Trusted packages&lt;&#x2F;h2&gt;
&lt;p&gt;Allows for packages which exclude source code or other elements which would be needed for verification of the contract bytecode.  This allows for minimalistic packages to be created for special situations where the package manager will not be performing verification.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;framework-support-and-integration&quot;&gt;Framework support and integration&lt;&#x2F;h1&gt;
&lt;p&gt;Support for ERC190 is either implemented or in progress for the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;truffleframework.com&#x2F;&quot;&gt;Truffle&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;populus.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;Populus&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dapple.readthedocs.io&#x2F;en&#x2F;master&#x2F;&quot;&gt;Dapple&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eris-ltd&#x2F;eris-cli&quot;&gt;Eris PM&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;iurimatias&#x2F;embark-framework&quot;&gt;Embark&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;remix-ide&#x2F;issues&#x2F;386&quot;&gt;Browser Solidity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ENS support for reverse resolution of Ethereum addresses</title>
        <published>2016-12-01T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><email>arachnid@notdot.net</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/181/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/181/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:181"
            label="ERC-181" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/181/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This EIP specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS. This permits associating a human-readable name with any Ethereum blockchain address. Resolvers can be certain that the reverse record was published by the owner of the Ethereum address in question.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;While name services are mostly used for forward resolution - going from human-readable identifiers to machine-readable ones - there are many use-cases in which reverse resolution is useful as well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Applications that allow users to monitor accounts benefit from showing the name of an account instead of its address, even if it was originally added by address.&lt;&#x2F;li&gt;
&lt;li&gt;Attaching metadata such as descriptive information to an address allows retrieving this information regardless of how the address was originally discovered.&lt;&#x2F;li&gt;
&lt;li&gt;Anyone can configure a name to resolve to an address, regardless of ownership of that address. Reverse records allow the owner of an address to claim a name as authoritative for that address.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;Reverse ENS records are stored in the ENS hierarchy in the same fashion as regular records, under a reserved domain, &lt;code&gt;addr.reverse&lt;&#x2F;code&gt;. To generate the ENS name for a given account&#x27;s reverse records, convert the account to hexadecimal representation in lower-case, and append &lt;code&gt;addr.reverse&lt;&#x2F;code&gt;. For instance, the ENS registry&#x27;s address at &lt;code&gt;0x112234455c3a32fd11230c42e7bccd4a84e02010&lt;&#x2F;code&gt; has any reverse records stored at &lt;code&gt;112234455c3a32fd11230c42e7bccd4a84e02010.addr.reverse&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this means that contracts wanting to do dynamic reverse resolution of addresses will need to perform hex encoding in the contract.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;registrar&quot;&gt;Registrar&lt;&#x2F;h2&gt;
&lt;p&gt;The owner of the &lt;code&gt;addr.reverse&lt;&#x2F;code&gt; domain will be a registrar that permits the caller to take ownership of
the reverse record for their own address. It provides the following methods:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;function-claim-address-owner-returns-bytes32-node&quot;&gt;function claim(address owner) returns (bytes32 node)&lt;&#x2F;h3&gt;
&lt;p&gt;When called by account &lt;code&gt;x&lt;&#x2F;code&gt;, instructs the ENS registry to transfer ownership of the name &lt;code&gt;hex(x) + &#x27;.addr.reverse&#x27;&lt;&#x2F;code&gt; to the provided address, and return the namehash of the ENS record thus transferred.&lt;&#x2F;p&gt;
&lt;p&gt;Allowing the caller to specify an owner other than themselves for the relevant node facilitates contracts that need accurate reverse ENS entries delegating this to their creators with a minimum of code inside their constructor:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;reverseRegistrar.claim(msg.sender)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;function-claimwithresolver-address-owner-address-resolver-returns-bytes32-node&quot;&gt;function claimWithResolver(address owner, address resolver) returns (bytes32 node)&lt;&#x2F;h3&gt;
&lt;p&gt;When called by account &lt;code&gt;x&lt;&#x2F;code&gt;, instructs the ENS registry to set the resolver of the name &lt;code&gt;hex(x) + &#x27;.addr.reverse&#x27;&lt;&#x2F;code&gt; to the specified resolver, then transfer ownership of the name to the provided address, and return the namehash of the ENS record thus transferred. This method facilitates setting up a custom resolver and owner in fewer transactions than would be required if calling &lt;code&gt;claim&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;function-setname-string-name-returns-bytes32-node&quot;&gt;function setName(string name) returns (bytes32 node)&lt;&#x2F;h3&gt;
&lt;p&gt;When called by account &lt;code&gt;x&lt;&#x2F;code&gt;, sets the resolver for the name &lt;code&gt;hex(x) + &#x27;.addr.reverse&#x27;&lt;&#x2F;code&gt; to a default resolver, and sets the name record on that name to the specified name. This method facilitates setting up simple reverse records for users in a single transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolver-interface&quot;&gt;Resolver interface&lt;&#x2F;h2&gt;
&lt;p&gt;A new resolver interface is defined, consisting of the following method:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function name(bytes32 node) constant returns (string);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Resolvers that implement this interface must return a valid ENS name for the requested node, or the empty string if no name is defined for the requested node.&lt;&#x2F;p&gt;
&lt;p&gt;The interface ID of this interface is 0x691f3431.&lt;&#x2F;p&gt;
&lt;p&gt;Future EIPs may specify more record types appropriate to reverse ENS records.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;appendix-1-registrar-implementation&quot;&gt;Appendix 1: Registrar implementation&lt;&#x2F;h1&gt;
&lt;p&gt;This registrar, written in Solidity, implements the specifications outlined above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pragma solidity ^0.4.10;&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;import &amp;quot;.&#x2F;AbstractENS.sol&amp;quot;;&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;contract Resolver {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function setName(bytes32 node, string name) public;&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&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; * @dev Provides a default implementation of a resolver for reverse records,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; * which permits only the owner to update it.&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;contract DefaultReverseResolver is Resolver {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    AbstractENS public ens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mapping(bytes32=&amp;gt;string) public name;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param ensAddr The address of the ENS registry.&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;    function DefaultReverseResolver(AbstractENS ensAddr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ens = ensAddr;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Only permits calls by the reverse registrar.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param node The node permission is required for.&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;    modifier owner_only(bytes32 node) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(msg.sender == ens.owner(node));&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;span class=&quot;giallo-l&quot;&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;     * @dev Sets the name for a node.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param node The node to update.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param _name The name to set.&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;    function setName(bytes32 node, string _name) public owner_only(node) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        name[node] = _name;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract ReverseRegistrar {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; namehash(&amp;#39;addr.reverse&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;&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;    AbstractENS public ens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Resolver public defaultResolver;&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;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param ensAddr The address of the ENS registry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param resolverAddr The address of the default reverse resolver.&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;    function ReverseRegistrar(AbstractENS ensAddr, Resolver resolverAddr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ens = ensAddr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        defaultResolver = resolverAddr;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Transfers ownership of the reverse ENS record associated with the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      calling account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param owner The address to set as the owner of the reverse record in ENS.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The ENS node hash of the reverse record.&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;    function claim(address owner) returns (bytes32 node) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return claimWithResolver(owner, 0);&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Transfers ownership of the reverse ENS record associated with the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      calling account.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param owner The address to set as the owner of the reverse record in ENS.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param resolver The address of the resolver to set; 0 to leave unchanged.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The ENS node hash of the reverse record.&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;    function claimWithResolver(address owner, address resolver) returns (bytes32 node) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        var label = sha3HexAddress(msg.sender);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        node = sha3(ADDR_REVERSE_NODE, label);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        var currentOwner = ens.owner(node);&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; Update the resolver if required&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(resolver != 0 &amp;amp;&amp;amp; resolver != ens.resolver(node)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Transfer the name to us first if it&amp;#39;s not already&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            if(currentOwner != address(this)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, this);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                currentOwner = address(this);&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;            ens.setResolver(node, resolver);&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&gt;        &#x2F;&#x2F; Update the owner if required&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(currentOwner != owner) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, 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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return node;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Sets the `name()` record for the reverse ENS record associated with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * the calling account. First updates the resolver to the default reverse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * resolver if necessary.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param name The name to set for this address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The ENS node hash of the reverse record.&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;    function setName(string name) returns (bytes32 node) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        node = claimWithResolver(this, defaultResolver);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        defaultResolver.setName(node, name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return node;&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev Returns the node hash for a given account&amp;#39;s reverse records.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param addr The address to hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The ENS node hash.&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;    function node(address addr) constant returns (bytes32 ret) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return sha3(ADDR_REVERSE_NODE, sha3HexAddress(addr));&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&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @dev An optimised function to compute the sha3 of the lower-case&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *      hexadecimal representation of an Ethereum address.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @param addr The address to hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     * @return The SHA3 hash of the lower-case hexadecimal encoding of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     *         input address.&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;    function sha3HexAddress(address addr) private returns (bytes32 ret) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        addr; ret; &#x2F;&#x2F; Stop warning us about unused variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            let i := 40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loop:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            i := sub(i, 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            mstore8(i, byte(and(addr, 0xf), lookup))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            addr := div(addr, 0x10)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            i := sub(i, 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            mstore8(i, byte(and(addr, 0xf), lookup))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            addr := div(addr, 0x10)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            jumpi(loop, i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ret := sha3(0, 40)&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;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;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Contract code size limit</title>
        <published>2016-11-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/170/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/170/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:170"
            label="EIP-170" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/170/">&lt;h3 id=&quot;hard-fork&quot;&gt;Hard fork&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;607&#x2F;&quot;&gt;Spurious Dragon&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MAX_CODE_SIZE&lt;&#x2F;code&gt;: &lt;code&gt;0x6000&lt;&#x2F;code&gt; (&lt;code&gt;2**14 + 2**13&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FORK_BLKNUM&lt;&#x2F;code&gt;: 2,675,000&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt;: 1 (Mainnet)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt;, then if contract creation initialization returns data with length of &lt;strong&gt;more than&lt;&#x2F;strong&gt; &lt;code&gt;MAX_CODE_SIZE&lt;&#x2F;code&gt; bytes, contract creation fails with an out of gas error.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Currently, there remains one slight quadratic vulnerability in Ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block&#x27;s proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern—not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;EIP-170 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;170&lt;&#x2F;li&gt;
&lt;li&gt;pyethereum implementation: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;blob&#x2F;5217294871283d8dc4fb3ca9d8a78c7d416490e8&#x2F;ethereum&#x2F;messages.py#L397&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Initial ENS Hash Registrar</title>
        <published>2016-10-25T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Maurelian</name>
	</author>
	
	<author>
		<name>Nick Johnson </name><email>nick@ethereum.org</email>
	</author>
	
	<author>
		<name>Alex Van de Sande</name><email>avsa@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/162/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/162/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:162"
            label="ERC-162" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/162/">&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Abstract&lt;&#x2F;li&gt;
&lt;li&gt;Motivations&lt;&#x2F;li&gt;
&lt;li&gt;Specification
&lt;ul&gt;
&lt;li&gt;Initial restrictions&lt;&#x2F;li&gt;
&lt;li&gt;Name format for hash registration&lt;&#x2F;li&gt;
&lt;li&gt;Auctioning names&lt;&#x2F;li&gt;
&lt;li&gt;Deeds&lt;&#x2F;li&gt;
&lt;li&gt;Deployment and Upgrade process&lt;&#x2F;li&gt;
&lt;li&gt;Registrar Interface&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rationale
&lt;ul&gt;
&lt;li&gt;Not committing to a permanent registrar at the outset&lt;&#x2F;li&gt;
&lt;li&gt;Valid names &amp;gt;= 7 characters&lt;&#x2F;li&gt;
&lt;li&gt;Restricting TLD to &lt;code&gt;.eth&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Holding ether as collateral&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Prior work&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!-- &#x2F;MarkdownTOC --&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This ERC describes the implementation, as deployed to the main ethereum network on 2017-05-04, of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). The corresponding source code is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;ens&#x2F;blob&#x2F;mainnet&#x2F;contracts&#x2F;HashRegistrarSimplified.sol&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For more background, refer to &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;EIP-137&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;EIP 137&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol.&lt;&#x2F;p&gt;
&lt;p&gt;In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and &quot;name squatting&quot;, however the best approach for mitigation is unclear. Thus an &quot;initial&quot; registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the &lt;code&gt;.eth&lt;&#x2F;code&gt; top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;ens&#x2F;blob&#x2F;mainnet&#x2F;contracts&#x2F;HashRegistrarSimplified.sol&quot;&gt;hash registrar implementation&lt;&#x2F;a&gt; in order to facilitate discussion.&lt;&#x2F;p&gt;
&lt;p&gt;The intent is to replace the Initial Registrar contract with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivations&quot;&gt;Motivations&lt;&#x2F;h2&gt;
&lt;p&gt;The following factors should be considered in order to optimize for adoption of the ENS, and good governance of the Initial Registrar&#x27;s namespace.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Upgradability:&lt;&#x2F;strong&gt; The Initial Registrar should be safely upgradeable, so that knowledge gained during its deployment can be used to replace it with an improved and permanent registrar.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Effective allocation:&lt;&#x2F;strong&gt; Newly released namespaces often create a land grab situation, resulting in many potentially valuable names being purchased but unused, with the hope of re-selling at a profit. This reduces the availability of the most useful names, in turn decreasing the utility of the name service to end users.&lt;&#x2F;p&gt;
&lt;p&gt;Achieving an effective allocation may or may not require human intervention for dispute resolution and other forms of curation. The Initial Registrar should not aim to create to most effective possible allocation, but instead limit the cost of misallocation in the long term.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Security:&lt;&#x2F;strong&gt; The registrar will hold a balance of ether without an explicit limit. It must be designed securely.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Simplicity:&lt;&#x2F;strong&gt; The ENS specification itself emphasizes a separation of concerns, allowing the most essential element, the registry to be as simple as possible. The interim registrar in turn should be as simple as possible while still meeting its other design goals.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Adoption:&lt;&#x2F;strong&gt; Successful standards become more successful due to network effects. The registrar should consider what strategies will encourage the adoption of the ENS in general, and the namespace it controls in particular.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;initial-restrictions&quot;&gt;Initial restrictions&lt;&#x2F;h3&gt;
&lt;p&gt;The Initial Registrar is expected to be in service for approximately two years, prior to upgrading. This should be sufficient time to learn, observe, and design an updated system.&lt;&#x2F;p&gt;
&lt;p&gt;During the initial two year period, the available name space will be restricted to the &lt;code&gt;.eth&lt;&#x2F;code&gt; TLD.&lt;&#x2F;p&gt;
&lt;p&gt;This restriction is enforced by the owner of the ENS root node who should not assign any nodes other than &lt;code&gt;.eth&lt;&#x2F;code&gt; to the Initial Registrar. The ENS&#x27;s root node should be controlled by multiple parties using a multisig contract.&lt;&#x2F;p&gt;
&lt;p&gt;The Initial Registrar will also prohibit registration of names 6 characters or less in length.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;name-format-for-hash-registration&quot;&gt;Name format for hash registration&lt;&#x2F;h3&gt;
&lt;p&gt;Names submitted to the initial registrar must be hashed using Ethereum&#x27;s sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in EIP 137.&lt;&#x2F;p&gt;
&lt;p&gt;For example, in order to register &lt;code&gt;abcdefg.eth&lt;&#x2F;code&gt;, one should submit &lt;code&gt;sha3(&#x27;abcdefg&#x27;)&lt;&#x2F;code&gt;, not &lt;code&gt;sha3(sha3(0, &#x27;eth&#x27;), &#x27;abcdefg&#x27;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;auctioning-names&quot;&gt;Auctioning names&lt;&#x2F;h3&gt;
&lt;p&gt;The registrar will allocate the available names through a Vickrey auction:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Vickrey auction is a type of sealed-bid auction. Bidders submit written bids without knowing the bid of the other people in the auction. The highest bidder wins but the price paid is the second-highest bid. This type of auction... gives bidders an incentive to bid their true value.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vickrey_auction&quot;&gt;Vickrey Auction, Wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The auction lifecycle of a name has 5 possible states, or Modes.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Not-yet-available:&lt;&#x2F;strong&gt; The majority of names will be initially unavailable for auction, and will become available some time during the 8 weeks after launch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Open:&lt;&#x2F;strong&gt; The earliest availability for a name is determined by the most significant byte of its sha3 hash. &lt;code&gt;0x00&lt;&#x2F;code&gt; would become available immediately, &lt;code&gt;0xFF&lt;&#x2F;code&gt; would become available after 8 weeks, and the availability of other names is distributed accordingly. Once a name is available, it is possible to start an auction on it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Auction:&lt;&#x2F;strong&gt; Once the auction for a name has begun, there is a 72 hour bidding period. Bidders must submit a payment of ether, along with sealed bids as a hash of &lt;code&gt;sha3(bytes32 hash, address owner, uint value, bytes32 salt)&lt;&#x2F;code&gt;. The bidder may obfuscate the true bid value by sending a greater amount of ether.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reveal:&lt;&#x2F;strong&gt; After the bidding period, a 48 hour reveal period commences. During this time, bidders must reveal the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of &quot;refund ratios&quot; outlined in the table below. If no bids are revealed, the name will return to the Open state.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Owned:&lt;&#x2F;strong&gt; After the reveal period has finished, the winning bidder must submit a transaction to finalize the auction, which then calls the ENS&#x27;s &lt;code&gt;setSubnodeOwner&lt;&#x2F;code&gt; function, recording the winning bidder&#x27;s address as the owner of the hash of the name.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The following table outlines important parameters which define the Registrar&#x27;s auction mechanism.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;registrar-parameters&quot;&gt;Registrar Parameters&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;totalAuctionLength&lt;&#x2F;td&gt;&lt;td&gt;The full time period from start of auction to end of the reveal period.&lt;&#x2F;td&gt;&lt;td&gt;5 days&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;revealPeriod&lt;&#x2F;td&gt;&lt;td&gt;The length of the time period during which bidding is no longer allowed, and bids must be revealed.&lt;&#x2F;td&gt;&lt;td&gt;48 hours&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;launchLength&lt;&#x2F;td&gt;&lt;td&gt;The time period during which all names will become available for auction.&lt;&#x2F;td&gt;&lt;td&gt;8 weeks&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;minPrice&lt;&#x2F;td&gt;&lt;td&gt;The minimum amount of ether which must be locked up in exchange for ownership of a name.&lt;&#x2F;td&gt;&lt;td&gt;0.01 ether&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;deeds&quot;&gt;Deeds&lt;&#x2F;h3&gt;
&lt;p&gt;The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in a separate &lt;code&gt;Deed&lt;&#x2F;code&gt; contracts. A deed contract is first created and funded when a sealed bid is submitted. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash. Non-winning bids are refunded.&lt;&#x2F;p&gt;
&lt;p&gt;A deed for an owned name may be transferred to another account by its owner, thus transferring ownership and control of the name.&lt;&#x2F;p&gt;
&lt;p&gt;After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them.&lt;&#x2F;p&gt;
&lt;p&gt;Deeds for non-winning bids can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.&lt;&#x2F;p&gt;
&lt;p&gt;The following table outlines what portion of the balance held in a deed contract will be returned upon closure, and to whom. The remaining balance will be burnt.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;refund-schedule&quot;&gt;Refund schedule&lt;&#x2F;h4&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Reason for Deed closure&lt;&#x2F;th&gt;&lt;th&gt;Refund Recipient&lt;&#x2F;th&gt;&lt;th&gt;Refund Percentage&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;A valid non-winning bid is revealed.&lt;&#x2F;td&gt;&lt;td&gt;Bidder&lt;&#x2F;td&gt;&lt;td&gt;99.5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;A bid submitted after the auction period is revealed.&lt;&#x2F;td&gt;&lt;td&gt;Bidder&lt;&#x2F;td&gt;&lt;td&gt;99.5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;An otherwise valid bid is revealed on an owned name. &lt;sup&gt;1&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;Bidder&lt;&#x2F;td&gt;&lt;td&gt;0.5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;An expired sealed bid is cancelled. &lt;sup&gt;2&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;Canceler&lt;&#x2F;td&gt;&lt;td&gt;0.5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;A registered hash is reported as invalid. &lt;sup&gt;3&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;Reporter&lt;&#x2F;td&gt;&lt;td&gt;50%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;A registered hash is reported as invalid. &lt;sup&gt;3&lt;&#x2F;sup&gt;&lt;&#x2F;td&gt;&lt;td&gt;Owner&lt;&#x2F;td&gt;&lt;td&gt;50%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h5 id=&quot;notes&quot;&gt;Notes:&lt;&#x2F;h5&gt;
&lt;ol&gt;
&lt;li&gt;This incentivizes all bids to be revealed in time. If bids could be revealed late, an extortion attack on the current highest bidder could be made by threatening to reveal a new second highest bid.&lt;&#x2F;li&gt;
&lt;li&gt;A bid which remains sealed after more than 2 weeks and 5 days may be cancelled by anyone to collect a small reward.&lt;&#x2F;li&gt;
&lt;li&gt;Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;deployment-and-upgrade-process&quot;&gt;Deployment and Upgrade process&lt;&#x2F;h3&gt;
&lt;p&gt;The Initial Registrar requires the ENS&#x27;s address as a constructor, and should be deployed after the ENS. The multisig account owning the root node in the ENS should then set the Initial Registrar&#x27;s address as owner of the &lt;code&gt;eth&lt;&#x2F;code&gt; node.&lt;&#x2F;p&gt;
&lt;p&gt;The Initial Registrar is expected to be replaced by a Permanent Registrar approximately 2 years after deployment. The following process should be used for the upgrade:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The Permanent Registrar contract will be deployed.&lt;&#x2F;li&gt;
&lt;li&gt;The multisig account owning the root node in the ENS will assign ownership of the &lt;code&gt;.eth&lt;&#x2F;code&gt; node to the Permanent Registrar.&lt;&#x2F;li&gt;
&lt;li&gt;Owners of hashes in the Initial Registrar will be responsible for registering their deeds to the Permanent Registrar. A couple options are considered here:
&lt;ol&gt;
&lt;li&gt;Require owners to transfer their ownership prior to a cutoff date in order to maintain ownership and&#x2F;or continue name resolution services.&lt;&#x2F;li&gt;
&lt;li&gt;Have the Permanent Registrar query the Initial Registrar for ownership if it is lacking an entry.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;planned-deactivation&quot;&gt;Planned deactivation&lt;&#x2F;h3&gt;
&lt;p&gt;In order to limit dependence on the Initial Registrar, new auctions will stop after 4 years, and all ether held in deeds after 8 years will become unreachable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;registrar-interface&quot;&gt;Registrar Interface&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;function state(bytes32 _hash) constant returns (Mode)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Implements a state machine returning the current state of a name&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function entries(bytes32 _hash) constant returns (Mode, address, uint, uint, uint)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Returns the following information regarding a registered name:
&lt;ul&gt;
&lt;li&gt;state&lt;&#x2F;li&gt;
&lt;li&gt;deed address&lt;&#x2F;li&gt;
&lt;li&gt;registration date&lt;&#x2F;li&gt;
&lt;li&gt;balance of the deed&lt;&#x2F;li&gt;
&lt;li&gt;highest value bid at auction&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function getAllowedTime(bytes32 _hash) constant returns (uint timestamp)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Returns the time at which the hash will no longer be in the initial &lt;code&gt;not-yet-available&lt;&#x2F;code&gt; state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function isAllowed(bytes32 _hash, uint _timestamp) constant returns (bool allowed)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Takes a hash and a time, returns true if and only if it has passed the initial &lt;code&gt;not-yet-available&lt;&#x2F;code&gt; state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function startAuction(bytes32 _hash);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Moves the state of a hash from Open to Auction. Throws if state is not Open.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function startAuctions(bytes32[] _hashes);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Starts multiple auctions on an array of hashes. This enables someone to open up an auction for a number of dummy hashes when they are only really interested in bidding for one. This will increase the cost for an attacker to simply bid blindly on all new auctions. Dummy auctions that are open but not bid on are closed after a week.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) constant returns (bytes32 sealedBid);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Takes the parameters of a bid, and returns the sealedBid hash value required to participate in the bidding for an auction. This obfuscates the parameters in order to mimic the mechanics of placing a bid in an envelope.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function newBid(bytes32 sealedBid);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bids are sent by sending a message to the main contract with a sealedBid hash and an amount of ether. The hash contains information about the bid, including the bidded name hash, the bid value, and a random salt. Bids are not tied to any one auction until they are revealed. The value of the bid itself can be masqueraded by sending more than the value of your actual bid. This is followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. Since this is an auction, it is expected that most public hashes, like known domains and common dictionary  words, will have multiple bidders pushing the price up.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function startAuctionsAndBid(bytes32[] hashes, bytes32 sealedBid)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A utility function allowing a call to &lt;code&gt;startAuctions&lt;&#x2F;code&gt; followed by &lt;code&gt;newBid&lt;&#x2F;code&gt; in a single transaction.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Once the bidding period is completed, there is a reveal period during with the properties of a bid are submitted to reveal them. The registrar hashes these properties using the &lt;code&gt;shaBid()&lt;&#x2F;code&gt; function above to verify that they match a pre-existing sealed bid. If the unsealedBid is the new best bid, the old best bid is returned to its bidder.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function cancelBid(bytes32 seal);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Cancels an unrevealed bid according to the rules described in the notes on the refund schedule above.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function finalizeAuction(bytes32 _hash);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After the registration date has passed, this function can be called to finalize the auction, which then calls the ENS function &lt;code&gt;setSubnodeOwner()&lt;&#x2F;code&gt;  updating the ENS record to set the winning bidder as owner of the node.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;function transfer(bytes32 _hash, address newOwner);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Update the owner of the ENS node corresponding to the submitted hash to a new owner. This function must be callable only by the current owner.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function releaseDeed(bytes32 _hash);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;After some time, the owner can release the property and get their ether back.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function invalidateName(string unhashedName);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Since registration is done on the hash of a name, the registrar itself cannot validate names. This function can be used to report a name which is 6 characters long or less. If it has been registered, the submitter will earn 10% of the deed value. We are purposefully handicapping the simplified registrar as a way to force it into being restructured in a few years.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function eraseNode(bytes32[] labels)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Allows anyone to delete the owner and resolver records for a subdomain of a name that is not currently owned in the registrar. For instance, to zero &lt;code&gt;foo.bar.eth&lt;&#x2F;code&gt; on a registrar that owns &lt;code&gt;.eth&lt;&#x2F;code&gt;, pass an array containing &lt;code&gt;[sha3(&#x27;foo&#x27;), sha3(&#x27;bar&#x27;)]&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;function transferRegistrars(bytes32 _hash) onlyOwner(_hash);&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Used during the upgrade process to a permanent registrar. If this registrar is no longer the owner of the its root node in the ENS, this function will transfers the deed to the current owner, which should be a new registrar. This function throws if this registrar still owns its root node.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;starting-with-a-temporary-registrar&quot;&gt;Starting with a temporary registrar&lt;&#x2F;h3&gt;
&lt;p&gt;Anticipating and designing for all the potential issues of name allocation names is unlikely to succeed. This approach chooses not to be concerned with getting it perfect, but allows us to observe and learn with training wheels on, and implement improvements before expanding the available namespace to shorter names or another TLD.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;valid-names-7-characters&quot;&gt;Valid names &amp;gt;= 7 characters&lt;&#x2F;h3&gt;
&lt;p&gt;Preserving the shortest, and often most valuable, domain names for the upgraded registrar provides the opportunity to implement processes for dispute resolution (assuming they are found to be necessary).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delayed-release-of-names&quot;&gt;Delayed release of names&lt;&#x2F;h3&gt;
&lt;p&gt;A slower release allows for extra time to identify, and address any issues which may arise after launch.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;restricting-tld-to-eth&quot;&gt;Restricting TLD to &lt;code&gt;.eth&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Choosing a single TLD helps to maximize network effects by focusing on one namespace.&lt;&#x2F;p&gt;
&lt;p&gt;A three letter TLD is a pattern made familiar by it&#x27;s common usage in internet domain names. This familiarity significantly increases the potential of the ENS to be integrated into pre-existing DNS systems, and reserved as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;special-use-domain-names&#x2F;special-use-domain-names.xhtml#special-use-domain&quot;&gt;special-use domain name&lt;&#x2F;a&gt;.  A recent precedent for this is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7686&quot;&gt;reservation of the &lt;code&gt;.onion&lt;&#x2F;code&gt; domain&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;holding-ether-as-collateral&quot;&gt;Holding ether as collateral&lt;&#x2F;h3&gt;
&lt;p&gt;This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prior-work&quot;&gt;Prior work&lt;&#x2F;h2&gt;
&lt;p&gt;This document borrows heavily from several sources:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;&quot;&gt;EIP-137&lt;&#x2F;a&gt; outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;26&quot;&gt;ERC-26&lt;&#x2F;a&gt; was the first ERC to propose a name service at the contract layer&lt;&#x2F;li&gt;
&lt;li&gt;@alexvandesande&#x27;s current implementation of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;ens&#x2F;blob&#x2F;mainnet&#x2F;contracts&#x2F;HashRegistrarSimplified.sol&quot;&gt;HashRegistrar&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;edits&quot;&gt;Edits:&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;2016-10-26 Added link Alex&#x27;s design in abstract&lt;&#x2F;li&gt;
&lt;li&gt;2016-11-01 change &#x27;Planned deactivation&#x27; to h3&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;2017-03-13 Update timelines for bidding and reveal periods&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>State trie clearing (invariant-preserving alternative)</title>
        <published>2016-10-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Gavin Wood</name><uri>https://github.com/gavofyork</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/161/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/161/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:161"
            label="EIP-161" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/161/">&lt;h3 id=&quot;hard-fork&quot;&gt;Hard fork&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;607&#x2F;&quot;&gt;Spurious Dragon&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FORK_BLKNUM&lt;&#x2F;code&gt;: 2,675,000&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt;: 1 (Mainnet)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;a. Account creation transactions and the &lt;code&gt;CREATE&lt;&#x2F;code&gt; operation SHALL, prior to the execution of the initialisation code, &lt;strong&gt;increment&lt;&#x2F;strong&gt; the &lt;strong&gt;nonce&lt;&#x2F;strong&gt; over and above its normal starting value by &lt;strong&gt;one&lt;&#x2F;strong&gt; (for normal networks, this will be simply 1, however test-nets with non-zero default starting nonces will be different).&lt;&#x2F;p&gt;
&lt;p&gt;b. Whereas &lt;code&gt;CALL&lt;&#x2F;code&gt; and &lt;code&gt;SUICIDE&lt;&#x2F;code&gt; would charge 25,000 gas when the destination is non-existent, now the charge SHALL &lt;strong&gt;only&lt;&#x2F;strong&gt; be levied if the operation transfers &lt;strong&gt;more than zero value&lt;&#x2F;strong&gt; and the destination account is &lt;em&gt;dead&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;c. No account may &lt;em&gt;change state&lt;&#x2F;em&gt; from non-existent to existent-but-&lt;em&gt;empty&lt;&#x2F;em&gt;. If an operation would do this, the account SHALL instead remain non-existent.&lt;&#x2F;p&gt;
&lt;p&gt;d. &lt;em&gt;At the end of the transaction&lt;&#x2F;em&gt;, any account &lt;em&gt;touched&lt;&#x2F;em&gt; by the execution of that transaction which is now &lt;em&gt;empty&lt;&#x2F;em&gt; SHALL instead become non-existent (i.e. &lt;strong&gt;deleted&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Where:&lt;&#x2F;p&gt;
&lt;p&gt;An account is considered to be &lt;em&gt;touched&lt;&#x2F;em&gt; when it is involved in any potentially &lt;em&gt;state-changing&lt;&#x2F;em&gt; operation. This includes, but is not limited to, being the recipient of a &lt;strong&gt;transfer of zero value&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An account is considered &lt;em&gt;empty&lt;&#x2F;em&gt; when it has &lt;strong&gt;no code&lt;&#x2F;strong&gt; and &lt;strong&gt;zero nonce&lt;&#x2F;strong&gt; and &lt;strong&gt;zero balance&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An account is considered &lt;em&gt;dead&lt;&#x2F;em&gt; when either it is non-existent or it is &lt;em&gt;empty&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;At the end of the transaction&lt;&#x2F;em&gt; is immediately following the execution of the suicide list, prior to the determination of the state trie root for receipt population.&lt;&#x2F;p&gt;
&lt;p&gt;An account &lt;em&gt;changes state&lt;&#x2F;em&gt; when:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;it is the target or refund of a &lt;code&gt;SUICIDE&lt;&#x2F;code&gt; operation for &lt;strong&gt;zero or more&lt;&#x2F;strong&gt; value;&lt;&#x2F;li&gt;
&lt;li&gt;it is the source or destination of a &lt;code&gt;CALL&lt;&#x2F;code&gt; operation or message-call transaction transferring &lt;strong&gt;zero or more&lt;&#x2F;strong&gt; value;&lt;&#x2F;li&gt;
&lt;li&gt;it is the source or creation of a &lt;code&gt;CREATE&lt;&#x2F;code&gt; operation or contract-creation transaction endowing &lt;strong&gt;zero or more&lt;&#x2F;strong&gt; value;&lt;&#x2F;li&gt;
&lt;li&gt;as the block author (&quot;miner&quot;) it is the recipient of block-rewards or transaction-fees of &lt;strong&gt;zero or more&lt;&#x2F;strong&gt; value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;notes&quot;&gt;Notes&lt;&#x2F;h4&gt;
&lt;p&gt;In the present Ethereum protocol, it should be noted that very few state changes can ultimately result in accounts that are empty following the execution of the transaction. In fact there are only four contexts that current implementations need track:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;an empty account has zero value transferred to it through &lt;code&gt;CALL&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;an empty account has zero value transferred to it through &lt;code&gt;SUICIDE&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;an empty account has zero value transferred to it through a message-call transaction;&lt;&#x2F;li&gt;
&lt;li&gt;an empty account has zero value transferred to it through a zero-gas-price fees transfer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Same as #158 except that several edge cases are avoided since we do not break invariants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;that an account can go from having code and storage to not having code or storage mid-way through the execution of a transaction;&lt;&#x2F;del&gt; [corrected]&lt;&#x2F;li&gt;
&lt;li&gt;that a newly created account cannot be deleted prior to being deployed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;CREATE&lt;&#x2F;code&gt; avoids zero in the nonce to avoid any suggestion of the oddity of &lt;code&gt;CREATE&lt;&#x2F;code&gt;d accounts being reaped half-way through their creation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;addendum-2017-08-15&quot;&gt;Addendum (2017-08-15)&lt;&#x2F;h3&gt;
&lt;p&gt;On 2016-11-24, a consensus bug occurred due to two implementations having different behavior in the case of state reverts.[3] The specification was amended to clarify that empty account deletions are reverted when the state is reverted.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;EIP-158 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;158&lt;&#x2F;li&gt;
&lt;li&gt;EIP-161 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;161&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2016&#x2F;11&#x2F;25&#x2F;security-alert-11242016-consensus-bug-geth-v1-4-19-v1-5-2&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Details: Geth was failing to revert empty account deletions when the transaction causing the deletions of empty accounts ended with an out-of-gas exception. An additional issue was found in Parity, where the Parity client incorrectly failed to revert empty account deletions in a more limited set of contexts involving out-of-gas calls to precompiled contracts; the new Geth behavior matches Parity’s, and empty accounts will cease to be a source of concern in general in about one week once the state clearing process finishes.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>EXP cost increase</title>
        <published>2016-10-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/160/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/160/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:160"
            label="EIP-160" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/160/">&lt;h3 id=&quot;hard-fork&quot;&gt;Hard fork&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;607&#x2F;&quot;&gt;Spurious Dragon&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FORK_BLKNUM&lt;&#x2F;code&gt;: 2,675,000&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt;: 1&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt;, increase the gas cost of EXP from 10 + 10 per byte in the exponent to 10 + 50 per byte in the exponent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Benchmarks suggest that EXP is currently underpriced by a factor of about 4–8.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;EIP-160 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;160&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>State clearing</title>
        <published>2016-10-16T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/158/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/158/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:158"
            label="EIP-158" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/158/">&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;For all blocks where &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt; (TBA):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;In all cases where a state change is made to an account, and this state change results in the account state being saved with nonce = 0, balance = 0, code empty, storage empty (hereinafter &quot;empty account&quot;), the account is instead deleted.&lt;&#x2F;li&gt;
&lt;li&gt;If an address is &quot;touched&quot; and that address contains an empty account, then it is deleted. A &quot;touch&quot; is defined as any situation where if the account at the given address were nonexistent it would be created.&lt;&#x2F;li&gt;
&lt;li&gt;Whenever the EVM checks if an account exists, emptiness is treated as equivalent to nonexistence. Particularly, note that this implies that, once this change is enabled, there is no longer a meaningful difference between emptiness and nonexistence from the point of view of EVM execution.&lt;&#x2F;li&gt;
&lt;li&gt;Zero-value calls and zero-value suicides no longer consume the 25000 account creation gas cost in any circumstance&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The cases where a &quot;touch&quot; takes place can be enumerated as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Zero-value-bearing CALLs&lt;&#x2F;li&gt;
&lt;li&gt;CREATEs (if the code that is ultimately saved is empty and there is no ether remaining in the account when it is saved)&lt;&#x2F;li&gt;
&lt;li&gt;Zero-value-bearing SUICIDEs&lt;&#x2F;li&gt;
&lt;li&gt;Transaction recipients&lt;&#x2F;li&gt;
&lt;li&gt;Contracts created in contract creation transactions&lt;&#x2F;li&gt;
&lt;li&gt;Miners receiving transaction fees (note the case where the gasprice is zero, and the account does not yet exist because it only receives the block&#x2F;uncle&#x2F;nephew rewards &lt;em&gt;after&lt;&#x2F;em&gt; processing every transaction)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;specification-1b&quot;&gt;Specification (1b)&lt;&#x2F;h3&gt;
&lt;p&gt;When the EVM checks for emptiness (for the purpose of possibly applying the 25000 gas cost), emptiness is defined by &lt;code&gt;is_empty(acct): return get_balance(acct) == 0 and get_code(acct) == &quot;&quot; and get_nonce(acct) == 0&lt;&#x2F;code&gt;; emptiness of storage does not matter. This simplifies client implementation because there is no need to add extra complexity to make caches enumerable in the correct way and does not significantly affect the intended result, as the cases where balance&#x2F;code&#x2F;nonce are empty but storage is nonempty where this change would lead to an extra 25000 gas being paid are pathological and have no real use value.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specification-1c&quot;&gt;Specification (1c)&lt;&#x2F;h3&gt;
&lt;p&gt;Do not implement point 2 above (ie. no new empty accounts can be created, but existing ones are not automatically destroyed unless their state is actually &lt;em&gt;changed&lt;&#x2F;em&gt;). Instead, during each block starting from (and including) N and ending when there are no null accounts left, select the 1000 null accounts that are left-most in order of sha3(address), and delete them (ordering by hash is necessary so as to allow the accounts to be easily found by iterating the tree).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h1&gt;
&lt;p&gt;This removes a large number of empty accounts that have been put in the state at very low cost due to flaws in earlier versions of the Ethereum protocol, thereby greatly reducing state size and hence both reducing the hard disk load of a full client and reducing the time for a fast sync. Additionally, it simplifies the protocol in the long term, as once all &quot;empty&quot; objects are cleared out there is no longer any meaningful distinction between an account being empty and being nonexistent, and indeed one can simply view nonexistence as a compact representation of emptiness.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this proposal does introduce a &lt;strong&gt;temporary&lt;&#x2F;strong&gt; breaking of existing guarantees, in that by repeatedly zero-value-calling already existing empty accounts one can create a state change at a cost of 700 gas per account instead of the usual 5000 per gas minimum (with SUICIDE refunds this goes down further to 350 gas per account). Allowing such a large number of state writes per block will lead to heightened block processing times and increase uncle rates in the short term while the existing empty accounts are being cleared, and eventually once all empty accounts are cleared this issue will no longer exist.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;EIP-158 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;158&lt;&#x2F;li&gt;
&lt;li&gt;EIP-161 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;161&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Simple replay attack protection</title>
        <published>2016-10-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/155/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/155/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:155"
            label="EIP-155" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/155/">&lt;h3 id=&quot;hard-fork&quot;&gt;Hard fork&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;607&#x2F;&quot;&gt;Spurious Dragon&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FORK_BLKNUM&lt;&#x2F;code&gt;: 2,675,000&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt;: 1 (main net)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt; and &lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt; is available, then when computing the hash of a transaction for the purposes of signing, instead of hashing only six rlp encoded elements &lt;code&gt;(nonce, gasprice, startgas, to, value, data)&lt;&#x2F;code&gt;, you &lt;strong&gt;SHOULD&lt;&#x2F;strong&gt; hash nine rlp encoded elements &lt;code&gt;(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)&lt;&#x2F;code&gt;.  If you do, then the &lt;code&gt;v&lt;&#x2F;code&gt; of the signature &lt;strong&gt;MUST&lt;&#x2F;strong&gt; be set to &lt;code&gt;{0,1} + CHAIN_ID * 2 + 35&lt;&#x2F;code&gt; where &lt;code&gt;{0,1}&lt;&#x2F;code&gt; is the parity of the &lt;code&gt;y&lt;&#x2F;code&gt; value of the curve point for which &lt;code&gt;r&lt;&#x2F;code&gt; is the x-value in the secp256k1 signing process.  If you choose to only hash 6 values, then &lt;code&gt;v&lt;&#x2F;code&gt; continues to be set to &lt;code&gt;{0,1} + 27&lt;&#x2F;code&gt; as previously.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt; and &lt;code&gt;v = CHAIN_ID * 2 + 35&lt;&#x2F;code&gt; or &lt;code&gt;v = CHAIN_ID * 2 + 36&lt;&#x2F;code&gt;, then when computing the hash of a transaction for purposes of recovering, instead of hashing six rlp encoded elements &lt;code&gt;(nonce, gasprice, startgas, to, value, data)&lt;&#x2F;code&gt;, hash nine rlp encoded elements &lt;code&gt;(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)&lt;&#x2F;code&gt;. The currently existing signature scheme using &lt;code&gt;v = 27&lt;&#x2F;code&gt; and &lt;code&gt;v = 28&lt;&#x2F;code&gt; remains valid and continues to operate under the same rules as it did previously.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;p&gt;Consider a transaction with &lt;code&gt;nonce = 9&lt;&#x2F;code&gt;, &lt;code&gt;gasprice = 20 * 10**9&lt;&#x2F;code&gt;, &lt;code&gt;startgas = 21000&lt;&#x2F;code&gt;, &lt;code&gt;to = 0x3535353535353535353535353535353535353535&lt;&#x2F;code&gt;, &lt;code&gt;value = 10**18&lt;&#x2F;code&gt;, &lt;code&gt;data=&#x27;&#x27;&lt;&#x2F;code&gt; (empty).&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;signing data&quot; becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080018080&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &quot;signing hash&quot; becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xdaf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the transaction is signed with the private key &lt;code&gt;0x4646464646464646464646464646464646464646464646464646464646464646&lt;&#x2F;code&gt;, then the v,r,s values become:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(37, 18515461264373351373200002665853028612451056578545711640558177340181847433846, 46948507304638947509940763649030358759909902576025900602547168820602576006531)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the use of 37 instead of 27. The signed tx would become:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;This would provide a way to send transactions that work on Ethereum without working on ETC or the Morden testnet. ETC is encouraged to adopt this EIP but replacing &lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt; with a different value, and all future testnets, consortium chains and alt-etherea are encouraged to adopt this EIP replacing &lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt; with a unique value.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;list-of-chain-id-s&quot;&gt;List of Chain ID&#x27;s:&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;code&gt;CHAIN_ID&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th&gt;Chain(s)&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;Ethereum mainnet&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Morden (disused), Expanse mainnet&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Ropsten&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;Rinkeby&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;Goerli&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;Kovan&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1337&lt;&#x2F;td&gt;&lt;td&gt;Geth private chains (default)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Find more chain ID&#x27;s on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chainid.network&quot;&gt;chainid.network&lt;&#x2F;a&gt; and contribute to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum-lists&#x2F;chains&quot;&gt;ethereum-lists&#x2F;chains&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Add BLAKE2 compression function `F` precompile</title>
        <published>2016-10-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Tjaden Hess</name><email>tah83@cornell.edu</email>
	</author>
	
	<author>
		<name>Matt Luongo</name><uri>https://github.com/mhluongo</uri>
	</author>
	
	<author>
		<name>Piotr Dyraga</name><uri>https://github.com/pdyraga</uri>
	</author>
	
	<author>
		<name>James Hancock</name><uri>https://github.com/MadeOfTin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/152/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/152" />
        

        <id>https://wg-eips.ritovision.com/152/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:152"
            label="EIP-152" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/152/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP will enable the BLAKE2b hash function and other higher-round 64-bit BLAKE2 variants to run cheaply on the EVM, allowing easier interoperability between Ethereum and Zcash as well as other Equihash-based PoW coins.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;This EIP introduces a new precompiled contract which implements the compression function &lt;code&gt;F&lt;&#x2F;code&gt; used in the BLAKE2 cryptographic hashing algorithm, for the purpose of allowing interoperability between the EVM and Zcash, as well as introducing more flexible cryptographic hash primitives to the EVM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;Besides being a useful cryptographic hash function and SHA3 finalist, BLAKE2 allows for efficient verification of the Equihash PoW used in Zcash, making a BTC Relay - style SPV client possible on Ethereum. A single verification of an Equihash PoW verification requires 512 iterations of the hash function, making verification of Zcash block headers prohibitively expensive if a Solidity implementation of BLAKE2 is used.&lt;&#x2F;p&gt;
&lt;p&gt;BLAKE2b, the common 64-bit BLAKE2 variant, is highly optimized and faster than MD5 on modern processors.&lt;&#x2F;p&gt;
&lt;p&gt;Interoperability with Zcash could enable contracts like trustless atomic swaps between the chains, which could provide a much needed aspect of privacy to the very public Ethereum blockchain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We propose adding a precompiled contract at address &lt;code&gt;0x09&lt;&#x2F;code&gt; wrapping the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7693#section-3.2&quot;&gt;BLAKE2 &lt;code&gt;F&lt;&#x2F;code&gt; compression function&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as explained below. The encoded inputs are corresponding to the ones specified in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7693#section-3.2&quot;&gt;BLAKE2 RFC Section 3.2&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rounds&lt;&#x2F;code&gt; - the number of rounds - 32-bit unsigned big-endian word&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;h&lt;&#x2F;code&gt; - the state vector - 8 unsigned 64-bit little-endian words&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;m&lt;&#x2F;code&gt; - the message block vector - 16 unsigned 64-bit little-endian words&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;t_0, t_1&lt;&#x2F;code&gt; - offset counters - 2 unsigned 64-bit little-endian words&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;f&lt;&#x2F;code&gt; - the final block indicator flag - 8-bit word&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The boolean &lt;code&gt;f&lt;&#x2F;code&gt; parameter is considered as &lt;code&gt;true&lt;&#x2F;code&gt; if set to &lt;code&gt;1&lt;&#x2F;code&gt;.
The boolean &lt;code&gt;f&lt;&#x2F;code&gt; parameter is considered as &lt;code&gt;false&lt;&#x2F;code&gt; if set to &lt;code&gt;0&lt;&#x2F;code&gt;.
All other values yield an invalid encoding of &lt;code&gt;f&lt;&#x2F;code&gt; error.&lt;&#x2F;p&gt;
&lt;p&gt;The precompile should compute the &lt;code&gt;F&lt;&#x2F;code&gt; function as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7693#section-3.2&quot;&gt;specified in the RFC&lt;&#x2F;a&gt; and return the updated state vector &lt;code&gt;h&lt;&#x2F;code&gt; with unchanged encoding (little-endian).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-usage-in-solidity&quot;&gt;Example Usage in Solidity&lt;&#x2F;h3&gt;
&lt;p&gt;The precompile can be wrapped easily in Solidity to provide a more development-friendly interface to &lt;code&gt;F&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; F&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; rounds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; h&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; m&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes8&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; t&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; f&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&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 class=&quot;z-support&quot;&gt;  bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; args &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rounds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; iszero&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;staticcall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;not&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x09&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xd5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x40&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;      revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; callF&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-support&quot;&gt;  uint32&lt;&#x2F;span&gt;&lt;span&gt; rounds &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  h&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5&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&gt;  h&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes32&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;6162630000000000000000000000000000000000000000000000000000000000&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&gt;  m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0000000000000000000000000000000000000000000000000000000000000000&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&gt;  m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0000000000000000000000000000000000000000000000000000000000000000&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&gt;  m&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0000000000000000000000000000000000000000000000000000000000000000&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bytes8&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  t&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0300000000000000&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&gt;  t&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;0000000000000000&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;  bool&lt;&#x2F;span&gt;&lt;span&gt; f &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Expected output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; F&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rounds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; h&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span&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&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;gas-costs-and-benchmarks&quot;&gt;Gas costs and benchmarks&lt;&#x2F;h3&gt;
&lt;p&gt;Each operation will cost &lt;code&gt;GFROUND * rounds&lt;&#x2F;code&gt; gas, where &lt;code&gt;GFROUND = 1&lt;&#x2F;code&gt;. Detailed benchmarks are presented in the benchmarks appendix section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h2&gt;
&lt;p&gt;BLAKE2 is an excellent candidate for precompilation. BLAKE2 is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively.&lt;&#x2F;p&gt;
&lt;p&gt;An obvious implementation would be a direct BLAKE2b hash function precompile. At first glance, a BLAKE2b precompile satisfies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects&#x27; requirements and libraries.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;152#issuecomment-499240310&quot;&gt;thread with the Zcash team&lt;&#x2F;a&gt; makes the issue clear.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The minimal thing that is necessary for a working ZEC-ETH relay is an implementation of BLAKE2b Compression F in a precompile.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A BLAKE2b Compression Function F precompile would also suffice for the Filecoin and Handshake interop goals.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A full BLAKE2b precompile would suffice for a ZEC-ETH relay, provided that the implementation provided the parts of the BLAKE2 API that we need (personalization, maybe something else—I&#x27;m not sure).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I&#x27;m not 100% certain if a full BLAKE2b precompile would also suffice for the Filecoin and Handshake goals. It almost certainly could, provided that it supports all the API that they need.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;BLAKE2s — whether the Compression Function F or the full hash — is only a nice-to-have for the purposes of a ZEC-ETH relay.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;From this and other conversations with teams in the space, we believe we should focus first on the &lt;code&gt;F&lt;&#x2F;code&gt; precompile as a strictly necessary piece for interoperability projects. A BLAKE2b precompile is a nice-to-have, and we support any efforts to add one-- but it&#x27;s unclear whether complete requirements and a flexible API can be found in time for Istanbul.&lt;&#x2F;p&gt;
&lt;p&gt;Implementation of only the core F compression function also allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at &lt;code&gt;0x09&lt;&#x2F;code&gt; being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;test-vector-0&quot;&gt;Test vector 0&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input: (empty)&lt;&#x2F;li&gt;
&lt;li&gt;output: error &quot;input length for BLAKE2 F precompile should be exactly 213 bytes&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-1&quot;&gt;Test vector 1&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: error &quot;input length for BLAKE2 F precompile should be exactly 213 bytes&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-2&quot;&gt;Test vector 2&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: error &quot;input length for BLAKE2 F precompile should be exactly 213 bytes&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-3&quot;&gt;Test vector 3&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: error &quot;incorrect final block indicator flag&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-4&quot;&gt;Test vector 4&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output:
&lt;code&gt;08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-5&quot;&gt;Test vector 5&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: &lt;code&gt;ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-6&quot;&gt;Test vector 6&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output:
&lt;code&gt;75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-7&quot;&gt;Test vector 7&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output:
&lt;code&gt;b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-vector-8&quot;&gt;Test vector 8&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;input:
&lt;code&gt;ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output:
&lt;code&gt;fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;An initial implementation of the &lt;code&gt;F&lt;&#x2F;code&gt; function in Go, adapted from the standard library, can be found in our &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;keep-network&#x2F;blake2-f&quot;&gt;Golang BLAKE2 library fork&lt;&#x2F;a&gt;. There&#x27;s also an implementation of the precompile in our fork of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;keep-network&#x2F;go-ethereum&#x2F;pull&#x2F;4&quot;&gt;go-ethereum&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;For reference, further discussion on this EIP also occurred in the following PRs and issues&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;152&quot;&gt;Original Issue&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;blake2b-f-precompile&#x2F;3157&quot;&gt;Ethereum Magicians&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;pull&#x2F;2129&quot;&gt;PR 2129&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-benchmarks&quot;&gt;Appendix - benchmarks&lt;&#x2F;h2&gt;
&lt;p&gt;Assuming ecRecover precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with ecRecover precompile. For benchmarks, we used 3.1 GHz Intel Core i7 64-bit machine.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; sysctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; machdep.cpu.brand_string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;Intel(R&lt;&#x2F;span&gt;&lt;span&gt;) Core(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;TM&lt;&#x2F;span&gt;&lt;span&gt;) i7-7920HQ CPU @ 3.10GHz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;12-rounds&quot;&gt;12 rounds&lt;&#x2F;h3&gt;
&lt;p&gt;An average gas price of F precompile call with 12 rounds compared to ecRecover should have been &lt;code&gt;6.74153&lt;&#x2F;code&gt; and it gives &lt;code&gt;0.5618&lt;&#x2F;code&gt; gas per round.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name                                         Gascost         Time (ns)     MGas&#x2F;S    Gasprice for 10MGas&#x2F;S    Gasprice for ECDSA eq&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;PrecompiledEcrecover&#x2F;                           3000  152636              19.6546                 1526.36               3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_0               12     338              35.503                     3.38                  6.64326&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_3               12     336              35.7143                    3.36                  6.60395&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_70              12     362              33.1492                    3.62                  7.11497&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_140             12     339              35.3982                    3.39                  6.66291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_230             12     339              35.3982                    3.39                  6.66291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_300             12     343              34.9854                    3.43                  6.74153&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_370             12     336              35.7143                    3.36                  6.60395&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_440             12     337              35.6083                    3.37                  6.6236&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_510             12     345              34.7826                    3.45                  6.78084&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_580             12     355              33.8028                    3.55                  6.97738&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Columns&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MGas&#x2F;S&lt;&#x2F;code&gt; - Shows what MGas per second was measured on that machine at that time&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Gasprice for 10MGas&#x2F;S&lt;&#x2F;code&gt; shows what the gasprice should have been, in order to reach 10 MGas&#x2F;second&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Gasprice for ECDSA eq&lt;&#x2F;code&gt; shows what the gasprice should have been, in order to have the same cost&#x2F;cycle as ecRecover&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;1200-rounds&quot;&gt;1200 rounds&lt;&#x2F;h3&gt;
&lt;p&gt;An average gas price of F precompile call with 1200 rounds compared to ecRecover should have been &lt;code&gt;436.1288&lt;&#x2F;code&gt; and it gives &lt;code&gt;0.3634&lt;&#x2F;code&gt; gas per round.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name                                         Gascost         Time (ns)     MGas&#x2F;S    Gasprice for 10MGas&#x2F;S    Gasprice for ECDSA eq&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;PrecompiledEcrecover&#x2F;                           3000  156152              19.212                  1561.52               3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_0             1200   22642              52.9989                  226.42                434.999&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_3             1200   22885              52.4361                  228.85                439.668&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_70            1200   22737              52.7774                  227.37                436.824&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_140           1200   22602              53.0926                  226.02                434.231&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_230           1200   22501              53.331                   225.01                432.29&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_300           1200   22435              53.4879                  224.35                431.022&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_370           1200   22901              52.3995                  229.01                439.975&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_440           1200   23134              51.8717                  231.34                444.452&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_510           1200   22608              53.0786                  226.08                434.346&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_580           1200   22563              53.1844                  225.63                433.481&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;1-round&quot;&gt;1 round&lt;&#x2F;h3&gt;
&lt;p&gt;An average gas price of F precompile call with 1 round compared to ecRecover should have been &lt;code&gt;2.431701&lt;&#x2F;code&gt;. However, in this scenario the call cost would totally overshadow the dynamic cost anyway.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name                                         Gascost         Time (ns)      MGas&#x2F;S    Gasprice for 10MGas&#x2F;S    Gasprice for ECDSA eq&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;PrecompiledEcrecover&#x2F;                           3000  157544              19.0423                  1575.44               3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_0                1     126               7.93651                    1.26                  2.39933&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_3                1     127               7.87402                    1.27                  2.41837&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_70               1     128               7.8125                     1.28                  2.43741&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_140              1     125               8                          1.25                  2.38029&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_230              1     128               7.8125                     1.28                  2.43741&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_300              1     127               7.87402                    1.27                  2.41837&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_370              1     131               7.63359                    1.31                  2.49454&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_440              1     129               7.75194                    1.29                  2.45646&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_510              1     125               8                          1.25                  2.38029&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrecompiledBlake2F&#x2F;testVectors2bX_580              1     131               7.63359                    1.31                  2.49454&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Gas cost changes for IO-heavy operations</title>
        <published>2016-09-24T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/150/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/150/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:150"
            label="EIP-150" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/150/">&lt;h3 id=&quot;meta-reference&quot;&gt;Meta reference&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;608&#x2F;&quot;&gt;Tangerine Whistle&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;FORK_BLKNUM&lt;&#x2F;th&gt;&lt;th&gt;CHAIN_ID&lt;&#x2F;th&gt;&lt;th&gt;CHAIN_NAME&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;2,463,000&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Main net&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= FORK_BLKNUM&lt;&#x2F;code&gt;, then:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Increase the gas cost of EXTCODESIZE to 700 (from 20).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the base gas cost of EXTCODECOPY to 700 (from 20).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the gas cost of BALANCE to 400 (from 20).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the gas cost of SLOAD to 200 (from 50).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the gas cost of CALL, DELEGATECALL, CALLCODE to 700 (from 40).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the gas cost of SELFDESTRUCT to 5000 (from 0).&lt;&#x2F;li&gt;
&lt;li&gt;If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs).&lt;&#x2F;li&gt;
&lt;li&gt;Increase the recommended gas limit target to 5.5 million.&lt;&#x2F;li&gt;
&lt;li&gt;Define &quot;all but one 64th&quot; of &lt;code&gt;N&lt;&#x2F;code&gt; as &lt;code&gt;N - floor(N &#x2F; 64)&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;If a call asks for more gas than the maximum allowed amount (i.e. the total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90&lt;sup&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;90&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; plus EIP-114&lt;sup&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;114&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;). CREATE only provides all but one 64th of the parent gas to the child call.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That is, substitute:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (value &amp;gt; 0) * opcodes.GCALLVALUETRANSFER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if compustate.gas &amp;lt; gas + extra_gas:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            return vm_exception(&amp;#39;OUT OF GAS&amp;#39;, needed=gas+extra_gas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        submsg_gas = gas + opcodes.GSTIPEND * (value &amp;gt; 0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        def max_call_gas(gas):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          return gas - (gas &#x2F;&#x2F; 64)&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;        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (value &amp;gt; 0) * opcodes.GCALLVALUETRANSFER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if compustate.gas &amp;lt; extra_gas:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            return vm_exception(&amp;#39;OUT OF GAS&amp;#39;, needed=extra_gas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if compustate.gas &amp;lt; gas + extra_gas:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            gas = min(gas, max_call_gas(compustate.gas - extra_gas))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        submsg_gas = gas + opcodes.GSTIPEND * (value &amp;gt; 0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Recent denial-of-service attacks have shown that opcodes that read the state tree are under-priced relative to other opcodes. There are software changes that have been made, are being made and can be made in order to mitigate the situation; however, the fact will remain that such opcodes will be by a substantial margin the easiest known mechanism to degrade network performance via transaction spam. The concern arises because it takes a long time to read from disk, and is additionally a risk to future sharding proposals as the &quot;attack transactions&quot; that have so far been most successful in degrading network performance would also require tens of megabytes to provide Merkle proofs for. This EIP increases the cost of storage reading opcodes to address this concern. The costs have been derived from an updated version of the calculation table used to generate the 1.0 gas costs: https:&#x2F;&#x2F;docs.google.com&#x2F;spreadsheets&#x2F;d&#x2F;15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ&#x2F;edit#gid=0; the rules attempt to target a limit of 8 MB of data that needs to be read in order to process a block, and include an estimate of 500 bytes for a Merkle proof for SLOAD and 1000 for an account.&lt;&#x2F;p&gt;
&lt;p&gt;This EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17–21 kb in the worst case).&lt;&#x2F;p&gt;
&lt;p&gt;The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like &lt;code&gt;msg.gas - 40&lt;&#x2F;code&gt; to determine how much gas to make a call with, relying on the gas cost of calls being 40. Additionally, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a &quot;softer&quot; gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls.&lt;&#x2F;p&gt;
&lt;p&gt;The gas limit increase is recommended so as to preserve the de-facto transactions-per-second processing capability of the system for average contracts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;EIP-90, https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;90&lt;&#x2F;li&gt;
&lt;li&gt;EIP-114, https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;114&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Change difficulty adjustment to target mean block time including uncles</title>
        <published>2016-04-28T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/100/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/100/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:100"
            label="EIP-100" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/100/">&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;Currently, the formula to compute the difficulty of a block includes the following logic:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adj_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;child_diff&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;difficulty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BLOCK_DIFF_FACTOR&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; adj_factor&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;difficulty&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MIN_DIFF&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= BYZANTIUM_FORK_BLKNUM&lt;&#x2F;code&gt;, we change the first line to the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adj_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;uncles&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;99&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;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;This new formula ensures that the difficulty adjustment algorithm targets a constant average rate of blocks produced including uncles, and so ensures a highly predictable issuance rate that cannot be manipulated upward by manipulating the uncle rate. A formula that accounts for the exact number of included uncles:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adj_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;uncles&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;timestamp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;99&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;can be fairly easily seen to be (to within a tolerance of ~3&#x2F;4194304) mathematically equivalent to assuming that a block with &lt;code&gt;k&lt;&#x2F;code&gt; uncles is equivalent to a sequence of &lt;code&gt;k+1&lt;&#x2F;code&gt; blocks that all appear with the exact same timestamp, and this is likely the simplest possible way to accomplish the desired effect. But since the exact formula depends on the full block and not just the header, we are instead using an approximate formula that accomplishes almost the same effect but has the benefit that it depends only on the block header (as you can check the uncle hash against the blank hash).&lt;&#x2F;p&gt;
&lt;p&gt;Changing the denominator from 10 to 9 ensures that the block time remains roughly the same (in fact, it should decrease by ~3% given the current uncle rate of 7%).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;EIP 100 issue and discussion: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;100&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;bitslog.wordpress.com&#x2F;2016&#x2F;04&#x2F;28&#x2F;uncle-mining-an-ethereum-consensus-protocol-flaw&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Ethereum Domain Name Service - Specification</title>
        <published>2016-04-04T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Nick Johnson</name><email>arachnid@notdot.net</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/137/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/137/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:137"
            label="ERC-137" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/137/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes.&lt;&#x2F;p&gt;
&lt;p&gt;The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as &#x27;vitalik.wallet&#x27; or &#x27;www.mysite.swarm&#x27;, and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve &#x27;mysite.swarm&#x27; to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;Existing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Registrar-ABI&quot;&gt;specifications&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum.gitbooks.io&#x2F;frontier-guide&#x2F;content&#x2F;registrar_services.html&quot;&gt;implementations&lt;&#x2F;a&gt; for name resolution in Ethereum provide basic functionality, but suffer several shortcomings that will significantly limit their long-term usefulness:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A single global namespace for all names with a single &#x27;centralised&#x27; resolver.&lt;&#x2F;li&gt;
&lt;li&gt;Limited or no support for delegation and sub-names&#x2F;sub-domains.&lt;&#x2F;li&gt;
&lt;li&gt;Only one record type, and no support for associating multiple copies of a record with a domain.&lt;&#x2F;li&gt;
&lt;li&gt;Due to a single global implementation, no support for multiple different name allocation systems.&lt;&#x2F;li&gt;
&lt;li&gt;Conflation of responsibilities: Name resolution, registration, and whois information.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Use-cases that these features would permit include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Support for subnames&#x2F;sub-domains - eg, live.mysite.tld and forum.mysite.tld.&lt;&#x2F;li&gt;
&lt;li&gt;Multiple services under a single name, such as a DApp hosted in Swarm, a Whisper address, and a mail server.&lt;&#x2F;li&gt;
&lt;li&gt;Support for DNS record types, allowing blockchain hosting of &#x27;legacy&#x27; names. This would permit an Ethereum client such as Mist to resolve the address of a traditional website, or the mail server for an email address, from a blockchain name.&lt;&#x2F;li&gt;
&lt;li&gt;DNS gateways, exposing ENS domains via the Domain Name Service, providing easier means for legacy clients to resolve and connect to blockchain services.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first two use-cases, in particular, can be observed everywhere on the present-day internet under DNS, and we believe them to be fundamental features of a name service that will continue to be useful as the Ethereum platform develops and matures.&lt;&#x2F;p&gt;
&lt;p&gt;The normative parts of this document does not specify an implementation of the proposed system; its purpose is to document a protocol that different resolver implementations can adhere to in order to facilitate consistent name resolution. An appendix provides sample implementations of resolver contracts and libraries, which should be treated as illustrative examples only.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, this document does not attempt to specify how domains should be registered or updated, or how systems can find the owner responsible for a given domain. Registration is the responsibility of registrars, and is a governance matter that will necessarily vary between top-level domains.&lt;&#x2F;p&gt;
&lt;p&gt;Updating of domain records can also be handled separately from resolution. Some systems, such as swarm, may require a well defined interface for updating domains, in which event we anticipate the development of a standard for this.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The ENS system comprises three main parts:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The ENS registry&lt;&#x2F;li&gt;
&lt;li&gt;Resolvers&lt;&#x2F;li&gt;
&lt;li&gt;Registrars&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The registry is a single contract that provides a mapping from any registered name to the resolver responsible for it, and permits the owner of a name to set the resolver address, and to create subdomains, potentially with different owners to the parent domain.&lt;&#x2F;p&gt;
&lt;p&gt;Resolvers are responsible for performing resource lookups for a name - for instance, returning a contract address, a content hash, or IP address(es) as appropriate. The resolver specification, defined here and extended in other EIPs, defines what methods a resolver may implement to support resolving different types of records.&lt;&#x2F;p&gt;
&lt;p&gt;Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.&lt;&#x2F;p&gt;
&lt;p&gt;Resolving a name in ENS is a two-step process. First, the ENS registry is called with the name to resolve, after hashing it using the procedure described below. If the record exists, the registry returns the address of its resolver. Then, the resolver is called, using the method appropriate to the resource being requested. The resolver then returns the desired result.&lt;&#x2F;p&gt;
&lt;p&gt;For example, suppose you wish to find the address of the token contract associated with &#x27;beercoin.eth&#x27;. First, get the resolver:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; node&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; namehash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;beercoin.eth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ens&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;resolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&gt;)&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;Then, ask the resolver for the address for the contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&gt;)&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 the &lt;code&gt;namehash&lt;&#x2F;code&gt; procedure depends only on the name itself, this can be precomputed and inserted into a contract, removing the need for string manipulation, and permitting O(1) lookup of ENS records regardless of the number of components in the raw name.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;name-syntax&quot;&gt;Name Syntax&lt;&#x2F;h2&gt;
&lt;p&gt;ENS names must conform to the following syntax:&lt;&#x2F;p&gt;
&lt;pre&gt;&amp;lt;domain&gt; ::= &amp;lt;label&gt; | &amp;lt;domain&gt; &quot;.&quot; &amp;lt;label&gt;
&amp;lt;label&gt; ::= any valid string label per [UTS46](https:&#x2F;&#x2F;unicode.org&#x2F;reports&#x2F;tr46&#x2F;)
&lt;&#x2F;pre&gt;
&lt;p&gt;In short, names consist of a series of dot-separated labels. Each label must be a valid normalised label as described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unicode.org&#x2F;reports&#x2F;tr46&#x2F;&quot;&gt;UTS46&lt;&#x2F;a&gt; with the options &lt;code&gt;transitional=false&lt;&#x2F;code&gt; and &lt;code&gt;useSTD3AsciiRules=true&lt;&#x2F;code&gt;. For Javascript implementations, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;idna-uts46&quot;&gt;library&lt;&#x2F;a&gt; is available that normalises and checks names.&lt;&#x2F;p&gt;
&lt;p&gt;Note that while upper and lower case letters are allowed in names, the UTS46 normalisation process case-folds labels before hashing them, so two names with different case but identical spelling will produce the same namehash.&lt;&#x2F;p&gt;
&lt;p&gt;Labels and domains may be of any length, but for compatibility with legacy DNS, it is recommended that labels be restricted to no more than 64 characters each, and complete ENS names to no more than 255 characters. For the same reason, it is recommended that labels do not start or end with hyphens, or start with digits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;namehash-algorithm&quot;&gt;namehash algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;Before being used in ENS, names are hashed using the &#x27;namehash&#x27; algorithm. This algorithm recursively hashes components of the name, producing a unique, fixed-length string for any valid input domain. The output of namehash is referred to as a &#x27;node&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;Pseudocode for the namehash algorithm is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def namehash(name):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  if name == &amp;#39;&amp;#39;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return &amp;#39;\0&amp;#39; * 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  else:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label, _, remainder = name.partition(&amp;#39;.&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return sha3(namehash(remainder) + sha3(label))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Informally, the name is split into labels, each label is hashed. Then, starting with the last component, the previous output is concatenated with the label hash and hashed again. The first component is concatenated with 32 &#x27;0&#x27; bytes. Thus, &#x27;mysite.swarm&#x27; is processed as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node = &amp;#39;\0&amp;#39; * 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node = sha3(node + sha3(&amp;#39;swarm&amp;#39;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node = sha3(node + sha3(&amp;#39;mysite&amp;#39;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Implementations should conform to the following test vectors for namehash:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;namehash(&amp;#39;&amp;#39;) = 0x0000000000000000000000000000000000000000000000000000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;namehash(&amp;#39;eth&amp;#39;) = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;namehash(&amp;#39;foo.eth&amp;#39;) = 0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;registry-specification&quot;&gt;Registry specification&lt;&#x2F;h2&gt;
&lt;p&gt;The ENS registry contract exposes the following functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&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;Returns the owner (registrar) of the specified node.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&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;Returns the resolver for the specified node.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ttl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&gt;)&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;Returns the time-to-live (TTL) of the node; that is, the maximum duration for which a node&#x27;s information may be cached.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&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;Transfers ownership of a node to another registrar. This function may only be called by the current owner of &lt;code&gt;node&lt;&#x2F;code&gt;. A successful call to this function logs the event &lt;code&gt;Transfer(bytes32 indexed, address)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setSubnodeOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; label&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&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;Creates a new node, &lt;code&gt;sha3(node, label)&lt;&#x2F;code&gt; and sets its owner to &lt;code&gt;owner&lt;&#x2F;code&gt;, or updates the node with a new owner if it already exists. This function may only be called by the current owner of &lt;code&gt;node&lt;&#x2F;code&gt;. A successful call to this function logs the event &lt;code&gt;NewOwner(bytes32 indexed, bytes32 indexed, address)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;)&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;Sets the resolver address for &lt;code&gt;node&lt;&#x2F;code&gt;. This function may only be called by the owner of &lt;code&gt;node&lt;&#x2F;code&gt;. A successful call to this function logs the event &lt;code&gt;NewResolver(bytes32 indexed, address)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTTL&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ttl&lt;&#x2F;span&gt;&lt;span&gt;)&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;Sets the TTL for a node. A node&#x27;s TTL applies to the &#x27;owner&#x27; and &#x27;resolver&#x27; records in the registry, as well as to any information returned by the associated resolver.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolver-specification&quot;&gt;Resolver specification&lt;&#x2F;h2&gt;
&lt;p&gt;Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions, the resolver MUST implement either all or none of them. Resolvers MUST specify a fallback function that throws.&lt;&#x2F;p&gt;
&lt;p&gt;Resolvers have one mandatory function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&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 &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; function is documented in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;165&#x2F;&quot;&gt;EIP-165&lt;&#x2F;a&gt;, and returns true if the resolver implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a resolver returns &lt;code&gt;true&lt;&#x2F;code&gt; for &lt;code&gt;supportsInterface()&lt;&#x2F;code&gt;, it must implement the functions specified in that interface.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;supportsInterface&lt;&#x2F;code&gt; must always return true for &lt;code&gt;0x01ffc9a7&lt;&#x2F;code&gt;, which is the interface ID of &lt;code&gt;supportsInterface&lt;&#x2F;code&gt; itself.&lt;&#x2F;p&gt;
&lt;p&gt;Currently standardised resolver interfaces are specified in the table below.&lt;&#x2F;p&gt;
&lt;p&gt;The following interfaces are defined:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Interface name&lt;&#x2F;th&gt;&lt;th&gt;Interface hash&lt;&#x2F;th&gt;&lt;th&gt;Specification&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;addr&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;0x3b3b57de&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;137&#x2F;#addr&quot;&gt;Contract address&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;name&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;0x691f3431&lt;&#x2F;td&gt;&lt;td&gt;#181&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ABI&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;0x2203ab56&lt;&#x2F;td&gt;&lt;td&gt;#205&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pubkey&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;0xc8690233&lt;&#x2F;td&gt;&lt;td&gt;#619&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;EIPs may define new interfaces to be added to this registry.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;contract-address-interface&quot;&gt;&lt;a name=&quot;addr&quot;&gt;&lt;&#x2F;a&gt;Contract Address Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Resolvers wishing to support contract address resources must provide the following function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&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 resolver supports &lt;code&gt;addr&lt;&#x2F;code&gt; lookups but the requested node does not have an addr record, the resolver MUST return the zero address.&lt;&#x2F;p&gt;
&lt;p&gt;Clients resolving the &lt;code&gt;addr&lt;&#x2F;code&gt; record MUST check for a zero return value, and treat this in the same manner as a name that does not have a resolver specified - that is, refuse to send funds to or interact with the address. Failure to do this can result in users accidentally sending funds to the 0 address.&lt;&#x2F;p&gt;
&lt;p&gt;Changes to an address MUST trigger the following event:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddrChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;appendix-a-registry-implementation&quot;&gt;Appendix A: Registry Implementation&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ENS&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Record&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;        uint64&lt;&#x2F;span&gt;&lt;span&gt; ttl&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; records&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NewOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; label&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; NewResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ENS&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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&gt;        records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;resolver&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ttl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ttl&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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&gt;        records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setSubnodeOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; label&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&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&gt;        var subnode &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; sha3&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; label&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        NewOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; label&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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&gt;        records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;subnode&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; resolver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        NewResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; resolver&lt;&#x2F;span&gt;&lt;span&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&gt;        records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;resolver &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; resolver&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setTTL&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ttl&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        NewTTL&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; ttl&lt;&#x2F;span&gt;&lt;span&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&gt;        records&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ttl &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ttl&lt;&#x2F;span&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;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;h1 id=&quot;appendix-b-sample-resolver-implementations&quot;&gt;Appendix B: Sample Resolver Implementations&lt;&#x2F;h1&gt;
&lt;h3 id=&quot;built-in-resolver&quot;&gt;Built-in resolver&lt;&#x2F;h3&gt;
&lt;p&gt;The simplest possible resolver is a contract that acts as its own name resolver by implementing the contract address resource profile:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; DoSomethingUseful&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Other code&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x3b3b57de&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        throw&lt;&#x2F;span&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;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;Such a contract can be inserted directly into the ENS registry, eliminating the need for a separate resolver contract in simple use-cases. However, the requirement to &#x27;throw&#x27; on unknown function calls may interfere with normal operation of some types of contract.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;standalone-resolver&quot;&gt;Standalone resolver&lt;&#x2F;h3&gt;
&lt;p&gt;A basic resolver that implements the contract address profile, and allows only its owner to update records:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Resolver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddrChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Resolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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&gt;        owner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setAddr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        AddrChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x3b3b57de&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        throw&lt;&#x2F;span&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;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;After deploying this contract, use it by updating the ENS registry to reference this contract for a name, then calling &lt;code&gt;setAddr()&lt;&#x2F;code&gt; with the same node to set the contract address it will resolve to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;public-resolver&quot;&gt;Public resolver&lt;&#x2F;h3&gt;
&lt;p&gt;Similar to the resolver above, this contract only supports the contract address profile, but uses the ENS registry to determine who should be allowed to update entries:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicResolver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; AddrChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-storage z-type&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ContentChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ENS ens&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ens&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; PublicResolver&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ensAddr&lt;&#x2F;span&gt;&lt;span&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&gt;        ens &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ENS&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ensAddr&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ret&lt;&#x2F;span&gt;&lt;span&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&gt;        ret &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; setAddr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; only_owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;node&lt;&#x2F;span&gt;&lt;span&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&gt;        addresses&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-entity z-name&quot;&gt;        AddrChanged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&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&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; interfaceID&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x3b3b57de&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; interfaceID &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x01ffc9a7&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        throw&lt;&#x2F;span&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;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;h1 id=&quot;appendix-c-sample-registrar-implementation&quot;&gt;Appendix C: Sample Registrar Implementation&lt;&#x2F;h1&gt;
&lt;p&gt;This registrar allows users to register names at no cost if they are the first to request them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FIFSRegistrar&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ENS ens&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; rootNode&lt;&#x2F;span&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 class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; FIFSRegistrar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; ensAddr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; node&lt;&#x2F;span&gt;&lt;span&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&gt;        ens &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; ENS&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ensAddr&lt;&#x2F;span&gt;&lt;span&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&gt;        rootNode &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; node&lt;&#x2F;span&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; register&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; subnode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&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&gt;        var node &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; sha3&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rootNode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; subnode&lt;&#x2F;span&gt;&lt;span&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&gt;        var currentOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ens&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;owner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;currentOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; currentOwner &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&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 class=&quot;z-keyword&quot;&gt;            throw&lt;&#x2F;span&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&gt;        ens&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;setSubnodeOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rootNode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; subnode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; owner&lt;&#x2F;span&gt;&lt;span&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&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;</content>
    </entry>
    <entry xml:lang="en">
        <title>Signed Data Standard</title>
        <published>2016-01-20T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Martin Holst Swende</name><uri>https://github.com/holiman</uri>
	</author>
	
	<author>
		<name>Nick Johnson</name><email>arachnid@notdot.net</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/191/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/EIPs/issues/191" />
        

        <id>https://wg-eips.ritovision.com/191/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:191"
            label="ERC-191" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/191/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This ERC proposes a specification about how to handle signed data in Ethereum contracts.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;Several multisignature wallet implementations have been created which accepts &lt;code&gt;presigned&lt;&#x2F;code&gt; transactions. A &lt;code&gt;presigned&lt;&#x2F;code&gt; transaction is a chunk of binary &lt;code&gt;signed_data&lt;&#x2F;code&gt;, along with signature (&lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; and &lt;code&gt;v&lt;&#x2F;code&gt;). The interpretation of the &lt;code&gt;signed_data&lt;&#x2F;code&gt; has not been specified, leading to several problems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Standard Ethereum transactions can be submitted as &lt;code&gt;signed_data&lt;&#x2F;code&gt;. An Ethereum transaction can be unpacked, into the following components: &lt;code&gt;RLP&amp;lt;nonce, gasPrice, startGas, to, value, data&amp;gt;&lt;&#x2F;code&gt; (hereby called &lt;code&gt;RLPdata&lt;&#x2F;code&gt;), &lt;code&gt;r&lt;&#x2F;code&gt;, &lt;code&gt;s&lt;&#x2F;code&gt; and &lt;code&gt;v&lt;&#x2F;code&gt;. If there are no syntactical constraints on &lt;code&gt;signed_data&lt;&#x2F;code&gt;, this means that &lt;code&gt;RLPdata&lt;&#x2F;code&gt; can be used as a syntactically valid &lt;code&gt;presigned&lt;&#x2F;code&gt; transaction.&lt;&#x2F;li&gt;
&lt;li&gt;Multisignature wallets have also had the problem that a &lt;code&gt;presigned&lt;&#x2F;code&gt; transaction has not been tied to a particular &lt;code&gt;validator&lt;&#x2F;code&gt;, i.e a specific wallet. Example:
&lt;ol&gt;
&lt;li&gt;Users &lt;code&gt;A&lt;&#x2F;code&gt;, &lt;code&gt;B&lt;&#x2F;code&gt; and &lt;code&gt;C&lt;&#x2F;code&gt; have the &lt;code&gt;2&#x2F;3&lt;&#x2F;code&gt;-wallet &lt;code&gt;X&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Users &lt;code&gt;A&lt;&#x2F;code&gt;, &lt;code&gt;B&lt;&#x2F;code&gt; and &lt;code&gt;D&lt;&#x2F;code&gt; have the &lt;code&gt;2&#x2F;3&lt;&#x2F;code&gt;-wallet &lt;code&gt;Y&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;User &lt;code&gt;A&lt;&#x2F;code&gt; and &lt;code&gt;B&lt;&#x2F;code&gt; submit &lt;code&gt;presigned&lt;&#x2F;code&gt; transactions to &lt;code&gt;X&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Attacker can now reuse their presigned transactions to &lt;code&gt;X&lt;&#x2F;code&gt;, and submit to &lt;code&gt;Y&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;p&gt;We propose the following format for &lt;code&gt;signed_data&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x19 &amp;lt;1 byte version&amp;gt; &amp;lt;version specific data&amp;gt; &amp;lt;data to sign&amp;gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The initial &lt;code&gt;0x19&lt;&#x2F;code&gt; byte is intended to ensure that the &lt;code&gt;signed_data&lt;&#x2F;code&gt; is not valid RLP.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That means that any &lt;code&gt;signed_data&lt;&#x2F;code&gt; cannot be one RLP-structure, but a 1-byte &lt;code&gt;RLP&lt;&#x2F;code&gt; payload followed by something else. Thus, any EIP-191 &lt;code&gt;signed_data&lt;&#x2F;code&gt; can never be an Ethereum transaction.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, &lt;code&gt;0x19&lt;&#x2F;code&gt; has been chosen because since ethereum&#x2F;go-ethereum#2940 , the following is prepended before hashing in personal_sign:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;\x19Ethereum Signed Message:\n&amp;quot; + len(message).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using &lt;code&gt;0x19&lt;&#x2F;code&gt; thus makes it possible to extend the scheme by defining a version &lt;code&gt;0x45&lt;&#x2F;code&gt; (&lt;code&gt;E&lt;&#x2F;code&gt;) to handle these kinds of signatures.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;registry-of-version-bytes&quot;&gt;Registry of version bytes&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Version byte&lt;&#x2F;th&gt;&lt;th&gt;EIP&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;191&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Data with intended validator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x01&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;712&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Structured data&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;0x45&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;191&#x2F;&quot;&gt;191&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;personal_sign&lt;&#x2F;code&gt; messages&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;version-0x00&quot;&gt;Version &lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x19 &amp;lt;0x00&amp;gt; &amp;lt;intended validator address&amp;gt; &amp;lt;data to sign&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The version &lt;code&gt;0x00&lt;&#x2F;code&gt; has &lt;code&gt;&amp;lt;intended validator address&amp;gt;&lt;&#x2F;code&gt; for the version specific data. In the case of a Multisig wallet that perform an execution based on a passed signature, the validator address is the address of the Multisig itself. The data to sign could be any arbitrary data.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;version-0x01&quot;&gt;Version &lt;code&gt;0x01&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The version &lt;code&gt;0x01&lt;&#x2F;code&gt; is for structured data as defined in &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;712&#x2F;&quot;&gt;EIP-712&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;version-0x45-e&quot;&gt;Version &lt;code&gt;0x45&lt;&#x2F;code&gt; (E)&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x19 &amp;lt;0x45 (E)&amp;gt; &amp;lt;thereum Signed Message:\n&amp;quot; + len(message)&amp;gt; &amp;lt;data to sign&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The version &lt;code&gt;0x45&lt;&#x2F;code&gt; (E) has &lt;code&gt;&amp;lt;thereum Signed Message:\n&quot; + len(message)&amp;gt;&lt;&#x2F;code&gt; for the version-specific data. The data to sign can be any arbitrary data.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;NB: The &lt;code&gt;E&lt;&#x2F;code&gt; in &lt;code&gt;Ethereum Signed Message&lt;&#x2F;code&gt; refers to the version byte 0x45. The character &lt;code&gt;E&lt;&#x2F;code&gt; is &lt;code&gt;0x45&lt;&#x2F;code&gt; in hexadecimal which makes the remainder, &lt;code&gt;thereum Signed Message:\n + len(message)&lt;&#x2F;code&gt;, the version-specific data.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;p&gt;The following snippets has been written in Solidity 0.8.0.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;version-0x00-1&quot;&gt;Version &lt;code&gt;0x00&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; signatureBasedExecution&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; payload&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; bytes32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 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&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Arguments when calculating hash to validate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1: byte(0x19) - the initial 0x19 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 2: byte(0) - the version byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 3: address(this) - the validator address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 4-6 : Application specific data&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 class=&quot;z-support&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; hash &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x19&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; byte&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nonce&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; payload&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; recovering the signer from the hash and the signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    addressRecovered &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; ecrecover&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&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&gt;   &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; logic of the wallet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; if (addressRecovered == owner) executeOnTarget(target, payload);&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;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Mixed-case checksum address encoding</title>
        <published>2016-01-14T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><email>vitalik.buterin@ethereum.org</email>
	</author>
	
	<author>
		<name>Alex Van de Sande</name><email>avsa@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/55/" type="text/html"/>
        
        
        <link rel="replies" type="text/html" href="https://github.com/ethereum/eips/issues/55" />
        

        <id>https://wg-eips.ritovision.com/55/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        

        
        <category
            term="tag:eip:55"
            label="ERC-55" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/55/">&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;Code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; eth_utils&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; checksum_encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Takes a 20-byte binary address as input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hex_addr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&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&gt;    checksummed_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Treat the hex address as ascii&#x2F;utf-8 for keccak256 hashing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hashed_address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; eth_utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;keccak&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;hex_addr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hex&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Iterate over each character in the hex address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; nibble_index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;hex_addr&lt;&#x2F;span&gt;&lt;span&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0123456789&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; We can&amp;#39;t upper-case the decimal digits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            checksummed_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;abcdef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;            #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Check if the corresponding hex digit (nibble) in the hash is 8 or higher&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            hashed_address_nibble&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;hashed_address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;nibble_index&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; hashed_address_nibble&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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&gt;                checksummed_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;upper&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&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&gt;                checksummed_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; character&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span&gt; eth_utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ValidationError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unrecognized hex character &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;character&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;!r&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; at position &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;nibble_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&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;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; checksummed_buffer&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function&quot;&gt;addr_str&lt;&#x2F;span&gt;&lt;span&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&gt;    addr_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; eth_utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_bytes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;hexstr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;addr_str&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    checksum_encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; checksum_encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;addr_bytes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; checksum_encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; addr_str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;checksum_encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; != expected &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;addr_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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&gt;test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&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;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In English, convert the address to hex, but if the &lt;code&gt;i&lt;&#x2F;code&gt;th digit is a letter (ie. it&#x27;s one of &lt;code&gt;abcdef&lt;&#x2F;code&gt;) print it in uppercase if the &lt;code&gt;4*i&lt;&#x2F;code&gt;th bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h1&gt;
&lt;p&gt;Benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time&lt;&#x2F;li&gt;
&lt;li&gt;Keeps the length at 40 characters&lt;&#x2F;li&gt;
&lt;li&gt;On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h1&gt;
&lt;p&gt;In javascript:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; createKeccakHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;keccak&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; toChecksumAddress&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toLowerCase&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-storage z-type&quot;&gt;  var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; createKeccakHash&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#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 class=&quot;z-storage z-type&quot;&gt;  var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&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 class=&quot;z-keyword&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;parseInt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-other&quot;&gt;      ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;toUpperCase&lt;&#x2F;span&gt;&lt;span&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&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&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 class=&quot;z-variable z-other&quot;&gt;      ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;i&lt;&#x2F;span&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;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 class=&quot;z-keyword&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; ret&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;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; toChecksumAddress(&amp;#39;0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;#39;0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i.e. the hex address encoded as ASCII):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    var hash = createKeccakHash(&amp;#39;keccak256&amp;#39;).update(Buffer.from(address.toLowerCase(), &amp;#39;ascii&amp;#39;)).digest()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;test-cases&quot;&gt;Test Cases&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# All caps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x52908400098527886E0F7030069857D2E4169EE7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x8617E340B3D01FA5F11F306F4090FD50E238070D&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# All Lower&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xde709f2102306220921060314715629080e2fb77&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x27b1fdb04752bbc536007a920d24acb045561c26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Normal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
    </entry>
    <entry xml:lang="en">
        <title>devp2p Forward Compatibility Requirements for Homestead</title>
        <published>2015-12-18T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:28+00:00</updated>
	
	
	<author>
		<name>Felix Lange</name><email>felix@ethdev.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/8/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/8/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="networking"
                label="Networking" />
            
        

        
        <category
            term="tag:eip:8"
            label="EIP-8" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/8/">&lt;h3 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP introduces new forward-compatibility requirements for implementations of the
devp2p Wire Protocol, the RLPx Discovery Protocol and the RLPx TCP Transport Protocol.
Clients which implement EIP-8 behave according to Postel&#x27;s Law:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Be conservative in what you do, be liberal in what you accept from others.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;Implementations of &lt;strong&gt;the devp2p Wire Protocol&lt;&#x2F;strong&gt; should ignore the version number of hello
packets. When sending the hello packet, the version element should be set to the highest
devp2p version supported. Implementations should also ignore any additional list elements
at the end of the hello packet.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, implementations of &lt;strong&gt;the RLPx Discovery Protocol&lt;&#x2F;strong&gt; should not validate the
version number of the ping packet, ignore any additional list elements in any packet, and
ignore any data after the first RLP value in any packet. Discovery packets with unknown
packet type should be discarded silently. The maximum size of any discovery packet is
still 1280 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, implementations of &lt;strong&gt;the RLPx TCP Transport protocol&lt;&#x2F;strong&gt; should accept a new
encoding for the encrypted key establishment handshake packets. If an EIP-8 style RLPx
&lt;code&gt;auth-packet&lt;&#x2F;code&gt; is received, the corresponding &lt;code&gt;ack-packet&lt;&#x2F;code&gt; should be sent using the rules
below.&lt;&#x2F;p&gt;
&lt;p&gt;Decoding the RLP data in &lt;code&gt;auth-body&lt;&#x2F;code&gt; and &lt;code&gt;ack-body&lt;&#x2F;code&gt; should ignore mismatches of &lt;code&gt;auth-vsn&lt;&#x2F;code&gt;
and &lt;code&gt;ack-vsn&lt;&#x2F;code&gt;, any additional list elements and any trailing data after the list. During
the transitioning period (i.e. until the old format has been retired), implementations
should pad &lt;code&gt;auth-body&lt;&#x2F;code&gt; with at least 100 bytes of junk data. Adding a random amount in
range [100, 300] is recommended to vary the size of the packet.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth-vsn         = 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth-size        = size of enc-auth-body, encoded as a big-endian 16-bit integer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth-body        = rlp.list(sig, initiator-pubk, initiator-nonce, auth-vsn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;enc-auth-body    = ecies.encrypt(recipient-pubk, auth-body, auth-size)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth-packet      = auth-size || enc-auth-body&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;ack-vsn          = 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ack-size         = size of enc-ack-body, encoded as a big-endian 16-bit integer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ack-body         = rlp.list(recipient-ephemeral-pubk, recipient-nonce, ack-vsn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;enc-ack-body     = ecies.encrypt(initiator-pubk, ack-body, ack-size)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ack-packet       = ack-size || enc-ack-body&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;where&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;X || Y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    denotes concatenation of X and Y.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X[:N]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    denotes an N-byte prefix of X.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rlp.list(X, Y, Z, ...)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    denotes recursive encoding of [X, Y, Z, ...] as an RLP list.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sha3(MESSAGE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    is the Keccak256 hash function as used by Ethereum.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ecies.encrypt(PUBKEY, MESSAGE, AUTHDATA)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    is the asymmetric authenticated encryption function as used by RLPx.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    AUTHDATA is authenticated data which is not part of the resulting ciphertext,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    but written to HMAC-256 before generating the message tag.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h3&gt;
&lt;p&gt;Changes to the devp2p protocols are hard to deploy because clients running an older
version will refuse communication if the version number or structure of the hello
(discovery ping, RLPx handshake) packet does not match local expectations.&lt;&#x2F;p&gt;
&lt;p&gt;Introducing forward-compatibility requirements as part of the Homestead consensus upgrade
will ensure that all client software in use on the Ethereum network can cope with future
network protocol upgrades (as long as backwards-compatibility is maintained).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;The proposed changes address forward compatibility by applying Postel&#x27;s Law (also known as
the Robustness Principle) throughout the protocol stack. The merit and applicability of
this approach has been studied repeatedly since its original application in RFC 761. For a
recent perspective, see
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;queue.acm.org&#x2F;detail.cfm?id=1999945&quot;&gt;&quot;The Robustness Principle Reconsidered&quot; (Eric Allman, 2011)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;changes-to-the-devp2p-wire-protocol&quot;&gt;Changes to the devp2p Wire Protocol&lt;&#x2F;h4&gt;
&lt;p&gt;All clients currently contain statements such as the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; pydevp2p&#x2F;p2p_protocol.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; proto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;version&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;debug&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;incompatible network protocols&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; peer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;proto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;peer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;        expected&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;proto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;version&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; received&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; proto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;send_disconnect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;reason&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;reasons&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;incompatible_p2p_version&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 checks make it impossible to change the version or structure of the hello packet.
Dropping them enables switching to a newer protocol version: Clients implementing a newer
version simply send a packet with higher version and possibly additional list elements.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If such a packet is received by a node with lower version, it will blindly assume that
the remote end is backwards-compatible and respond with the old handshake.&lt;&#x2F;li&gt;
&lt;li&gt;If the packet is received by a node with equal version, new features of the protocol can
be used.&lt;&#x2F;li&gt;
&lt;li&gt;If the packet is received by a node with higher version, it can enable
backwards-compatibility logic or drop the connection.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;changes-to-the-rlpx-discovery-protocol&quot;&gt;Changes to the RLPx Discovery Protocol&lt;&#x2F;h4&gt;
&lt;p&gt;The relaxation of discovery packet decoding rules largely codifies current practice. Most
existing implementations do not care about the number of list elements (an exception being
go-ethereum) and do not reject nodes with mismatching version. This behaviour is not
guaranteed by the spec, though.&lt;&#x2F;p&gt;
&lt;p&gt;If adopted, the change makes it possible to deploy protocol changes in a similar manner to
the devp2p hello change: simply bump the version and send additional information. Older
clients will ignore the additional elements and can continue to operate even when the
majority of the network has moved on to a newer protocol.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;changes-to-the-rlpx-tcp-handshake&quot;&gt;Changes to the RLPx TCP Handshake&lt;&#x2F;h4&gt;
&lt;p&gt;Discussions of the RLPx v5 changes (chunked packets, change to key derivation) have
faltered in part because the v4 handshake encoding provides only one in-band way to add a
version number: shortening the random portion of the nonce. Even if the RLPx v5 handshake
proposal were accepted, future upgrades are hard because the handshake packet is a fixed
size ECIES ciphertext with known layout.&lt;&#x2F;p&gt;
&lt;p&gt;I propose the following changes to the handshake packets:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Adding the length of the ciphertext as a plaintext header.&lt;&#x2F;li&gt;
&lt;li&gt;Encoding the body of the handshake as RLP.&lt;&#x2F;li&gt;
&lt;li&gt;Adding a version number to both packets in place of the token flag (unused).&lt;&#x2F;li&gt;
&lt;li&gt;Removing the hash of the ephemeral public key (it is redundant).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These changes make it possible to upgrade the RLPx TCP transport protocol in the same
manner as described for the other protocols, i.e. by adding list elements and bumping the
version. Since this is the first change to the RLPx handshake packet, we can seize the
opportunity to remove all currently unused fields.&lt;&#x2F;p&gt;
&lt;p&gt;Additional data is permitted (and in fact required) after the RLP list because the
handshake packet needs to grow in order to be distinguishable from the old format.
Clients can employ logic such as the following pseudocode to handle both formats
simultaneously.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;packet&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; read&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;307&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; connection&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decrypt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;packet&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; process as old format&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 class=&quot;z-keyword&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 class=&quot;z-variable z-other&quot;&gt;    size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; unpack_16bit_big_endian&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;packet&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;    packet&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; read&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 307&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; connection&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;decrypt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;packet&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; error&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 class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; process as new format&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 plain text size prefix is perhaps the most controversial aspect of this document. It
has been argued that the prefix aids adversaries that seek to filter and identify RLPx
connections on the network level.&lt;&#x2F;p&gt;
&lt;p&gt;This is largely a question of how much effort the adversary is willing to expense. If the
recommendation to randomise the lengths is followed, pure pattern-based packet
recognition is unlikely to succeed.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For typical firewall operators, blocking all connections whose first two bytes form an
integer in range [300,600] is probably too invasive. Port-based blocking would be
a more effective measure to filter most RLPx traffic.&lt;&#x2F;li&gt;
&lt;li&gt;For an attacker who can afford to correlate many criteria, the size prefix would ease
recognition because it adds to the indicator set. However, such an attacker could also
be expected to read or participate in RLPx Discovery traffic, which would be sufficient
to enable blocking of RLPx TCP connections whatever their format is.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP is backwards-compatible, all valid version 4 packets are still accepted.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;pull&#x2F;2091&quot;&gt;go-ethereum&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;libweb3core&#x2F;pull&#x2F;46&quot;&gt;libweb3core&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pydevp2p&#x2F;pull&#x2F;32&quot;&gt;pydevp2p&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;test-vectors&quot;&gt;Test Vectors&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;devp2p-base-protocol&quot;&gt;devp2p Base Protocol&lt;&#x2F;h4&gt;
&lt;p&gt;devp2p hello packet advertising version 22 and containing a few additional list elements:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f87137916b6e6574682f76302e39312f706c616e39cdc5836574683dc6846d6f726b1682270fb840&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877c883666f6f836261720304&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;rlpx-discovery-protocol&quot;&gt;RLPx Discovery Protocol&lt;&#x2F;h4&gt;
&lt;p&gt;Implementations should accept the following encoded discovery packets as valid.
The packets are signed using the secp256k1 node key&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ping packet with version 4, additional list elements:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e9614ccfd9fc3e74360018522d30e1419a143407ffcce748de3e22116b7e8dc92ff74788c0b6663a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;aa3d67d641936511c8f8d6ad8698b820a7cf9e1be7155e9a241f556658c55428ec0563514365799a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4be2be5a685a80971ddcfa80cb422cdd0101ec04cb847f000001820cfa8215a8d790000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;000000000000000000018208ae820d058443b9a3550102&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ping packet with version 555, additional list elements and additional random data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba7602&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee191&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6d922dc3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;pong packet with additional list elements and additional random data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b206&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f0555&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;42124e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;findnode packet with additional list elements and additional random data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c7c44041b9f7c7e41934417ebac9a8e1a4c6298f74553f2fcfdcae6ed6fe53163eb3d2b52e39fe91&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;831b8a927bf4fc222c3902202027e5e9eb812195f95d20061ef5cd31d502e47ecb61183f74a504fe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;04c51e73df81f25c4d506b26db4517490103f84eb840ca634cae0d49acb401d8a4c6b6fe8c55b70d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be0081290476&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7bf5ccd1fc7f8443b9a35582999983999999280dc62cc8255c73471e0a61da0c89acdc0e035e260a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dd7fc0c04ad9ebf3919644c91cb247affc82b69bd2ca235c71eab8e49737c937a2c396&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;neighbours packet with additional list elements and additional random data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c679fc8fe0b8b12f06577f2e802d34f6fa257e6137a995f6f4cbfc9ee50ed3710faf6e66f932c4c8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d81d64343f429651328758b47d3dbc02c4042f0fff6946a50f4a49037a72bb550f3a7872363a83e1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b9ee6469856c24eb4ef80b7535bcf99c0004f9015bf90150f84d846321163782115c82115db84031&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;55e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa8291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;15d224c523596b401065a97f74010610fce76382c0bf32f84984010203040101b840312c55512422&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e82&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9f04c2d314fc2d4e255e0d3bc08792b069dbf8599020010db83c4d001500000000abcdef12820d05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;820d05b84038643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aacf8599020010db885a308d3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13198a2e037073488203e78203e8b8408dcab8618c3253b558d459da53bd8fa68935a719aff8b811&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df73&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8443b9a355010203b525a138aa34383fec3d2719a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;rlpx-handshake&quot;&gt;RLPx Handshake&lt;&#x2F;h4&gt;
&lt;p&gt;In these test vectors, node A initiates a connection with node B.
The values contained in all packets are given below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Static Key A:    49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Static Key B:    b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ephemeral Key A: 869d6ecf5211f1cc60418a13b9d870b22959d0c16f02bec714c960dd2298a32d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ephemeral Key B: e238eb8e04fee6511ab04c6dd3c89ce097b11f25d584863ac2b6d5b35b1847e4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce A:         7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nonce B:         559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Auth₁)  RLPx v4 format (sent from A to B):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;048ca79ad18e4b0659fab4853fe5bc58eb83992980f4c9cc147d2aa31532efd29a3d3dc6a3d89eaf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;913150cfc777ce0ce4af2758bf4810235f6e6ceccfee1acc6b22c005e9e3a49d6448610a58e98744&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ba3ac0399e82692d67c1f58849050b3024e21a52c9d3b01d871ff5f210817912773e610443a9ef14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2e91cdba0bd77b5fdf0769b05671fc35f83d83e4d3b0b000c6b2a1b1bba89e0fc51bf4e460df3105&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c444f14be226458940d6061c296350937ffd5e3acaceeaaefd3c6f74be8e23e0f45163cc7ebd7622&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0f0128410fd05250273156d548a414444ae2f7dea4dfca2d43c057adb701a715bf59f6fb66b2d1d2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0f2c703f851cbf5ac47396d9ca65b6260bd141ac4d53e2de585a73d1750780db4c9ee4cd4d225173&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a4592ee77e2bd94d0be3691f3b406f9bba9b591fc63facc016bfa8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Auth₂) EIP-8 format with version 4 and no additional list elements (sent from A to B):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01b304ab7578555167be8154d5cc456f567d5ba302662433674222360f08d5f1534499d3678b513b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0fca474f3a514b18e75683032eb63fccb16c156dc6eb2c0b1593f0d84ac74f6e475f1b8d56116b84&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9634a8c458705bf83a626ea0384d4d7341aae591fae42ce6bd5c850bfe0b999a694a49bbbaf3ef6c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;da61110601d3b4c02ab6c30437257a6e0117792631a4b47c1d52fc0f8f89caadeb7d02770bf999cc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;147d2df3b62e1ffb2c9d8c125a3984865356266bca11ce7d3a688663a51d82defaa8aad69da39ab6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d5470e81ec5f2a7a47fb865ff7cca21516f9299a07b1bc63ba56c7a1a892112841ca44b6e0034dee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;70c9adabc15d76a54f443593fafdc3b27af8059703f88928e199cb122362a4b35f62386da7caad09&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c001edaeb5f8a06d2b26fb6cb93c52a9fca51853b68193916982358fe1e5369e249875bb8d0d0ec3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6f917bc5e1eafd5896d46bd61ff23f1a863a8a8dcd54c7b109b771c8e61ec9c8908c733c0263440e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2aa067241aaa433f0bb053c7b31a838504b148f570c0ad62837129e547678c5190341e4f1693956c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3bf7678318e2d5b5340c9e488eefea198576344afbdf66db5f51204a6961a63ce072c8926c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Auth₃) EIP-8 format with version 56 and 3 additional list elements (sent from A to B):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01b8044c6c312173685d1edd268aa95e1d495474c6959bcdd10067ba4c9013df9e40ff45f5bfd6f7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2471f93a91b493f8e00abc4b80f682973de715d77ba3a005a242eb859f9a211d93a347fa64b597bf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;280a6b88e26299cf263b01b8dfdb712278464fd1c25840b995e84d367d743f66c0e54a586725b7bb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f12acca27170ae3283c1073adda4b6d79f27656993aefccf16e0d0409fe07db2dc398a1b7e8ee93b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd181485fd332f381d6a050fba4c7641a5112ac1b0b61168d20f01b479e19adf7fdbfa0905f63352&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bfc7e23cf3357657455119d879c78d3cf8c8c06375f3f7d4861aa02a122467e069acaf513025ff19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6641f6d2810ce493f51bee9c966b15c5043505350392b57645385a18c78f14669cc4d960446c1757&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1b7c5d725021babbcd786957f3d17089c084907bda22c2b2675b4378b114c601d858802a55345a15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;116bc61da4193996187ed70d16730e9ae6b3bb8787ebcaea1871d850997ddc08b4f4ea668fbf3740&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7ac044b55be0908ecb94d4ed172ece66fd31bfdadf2b97a8bc690163ee11f5b575a4b44e36e2bfb2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f0fce91676fd64c7773bac6a003f481fddd0bae0a1f31aa27504e2a533af4cef3b623f4791b2cca6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d490&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Ack₁) RLPx v4 format (sent from B to A):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;049f8abcfa9c0dc65b982e98af921bc0ba6e4243169348a236abe9df5f93aa69d99cadddaa387662&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b0ff2c08e9006d5a11a278b1b3331e5aaabf0a32f01281b6f4ede0e09a2d5f585b26513cb794d963&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5a57563921c04a9090b4f14ee42be1a5461049af4ea7a7f49bf4c97a352d39c8d02ee4acc416388c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1c66cec761d2bc1c72da6ba143477f049c9d2dde846c252c111b904f630ac98e51609b3b1f58168d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dca6505b7196532e5f85b259a20c45e1979491683fee108e9660edbf38f3add489ae73e3dda2c71b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d1497113d5c755e942d1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Ack₂) EIP-8 format with version 4 and no additional list elements (sent from B to A):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01ea0451958701280a56482929d3b0757da8f7fbe5286784beead59d95089c217c9b917788989470&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b0e330cc6e4fb383c0340ed85fab836ec9fb8a49672712aeabbdfd1e837c1ff4cace34311cd7f4de&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;05d59279e3524ab26ef753a0095637ac88f2b499b9914b5f64e143eae548a1066e14cd2f4bd7f814&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4652f11b254f8a2d0191e2f5546fae6055694aed14d906df79ad3b407d94692694e259191cde171&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ad542fc588fa2b7333313d82a9f887332f1dfc36cea03f831cb9a23fea05b33deb999e85489e645f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6aab1872475d488d7bd6c7c120caf28dbfc5d6833888155ed69d34dbdc39c1f299be1057810f34fb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e754d021bfca14dc989753d61c413d261934e1a9c67ee060a25eefb54e81a4d14baff922180c395d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3f998d70f46f6b58306f969627ae364497e73fc27f6d17ae45a413d322cb8814276be6ddd13b885b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;201b943213656cde498fa0e9ddc8e0b8f8a53824fbd82254f3e2c17e8eaea009c38b4aa0a3f306e8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;797db43c25d68e86f262e564086f59a2fc60511c42abfb3057c247a8a8fe4fb3ccbadde17514b7ac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8000cdb6a912778426260c47f38919a91f25f4b5ffb455d6aaaf150f7e5529c100ce62d6d92826a7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1778d809bdf60232ae21ce8a437eca8223f45ac37f6487452ce626f549b3b5fdee26afd2072e4bc7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5833c2464c805246155289f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(Ack₃) EIP-8 format with version 57 and 3 additional list elements (sent from B to A):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01f004076e58aae772bb101ab1a8e64e01ee96e64857ce82b1113817c6cdd52c09d26f7b90981cd7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ae835aeac72e1573b8a0225dd56d157a010846d888dac7464baf53f2ad4e3d584531fa203658fab0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3a06c9fd5e35737e417bc28c1cbf5e5dfc666de7090f69c3b29754725f84f75382891c561040ea1d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dc0d8f381ed1b9d0d4ad2a0ec021421d847820d6fa0ba66eaf58175f1b235e851c7e2124069fbc20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2888ddb3ac4d56bcbd1b9b7eab59e78f2e2d400905050f4a92dec1c4bdf797b3fc9b2f8e84a482f3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d800386186712dae00d5c386ec9387a5e9c9a1aca5a573ca91082c7d68421f388e79127a5177d4f8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;590237364fd348c9611fa39f78dcdceee3f390f07991b7b47e1daa3ebcb6ccc9607811cb17ce51f1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c8c2c5098dbdd28fca547b3f58c01a424ac05f869f49c6a34672ea2cbbc558428aa1fe48bbfd6115&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8b1b735a65d99f21e70dbc020bfdface9f724a0d1fb5895db971cc81aa7608baa0920abb0a565c9c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;436e2fd13323428296c86385f2384e408a31e104670df0791d93e743a3a5194ee6b076fb6323ca59&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3011b7348c16cf58f66b9633906ba54a2ee803187344b394f75dd2e663a57b956cb830dd7a908d4f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;39a2336a61ef9fda549180d4ccde21514d117b6c6fd07a9102b5efe710a32af4eeacae2cb3b1dec0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;35b9593b48b9d3ca4c13d245d5f04169b0b1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Node B derives the connection secrets for (Auth₂, Ack₂) as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;aes-secret = 80e8632c05fed6fc2a13b0f8d31a3cf645366239170ea067065aba8e28bac487&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mac-secret = 2ea74ec5dae199227dff1af715362700e989d889d7a493cb0639691efb8e5f98&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running B&#x27;s &lt;code&gt;ingress-mac&lt;&#x2F;code&gt; keccak state on the string &quot;foo&quot; yields the hash&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ingress-mac(&amp;quot;foo&amp;quot;) = 0c7ec6340062cc46f5e9f1e3cf86f8c8c403c5a0964f5df0ebd34a75ddc86db5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h3&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Gas Usage for `RETURN` and `CALL*`</title>
        <published>2015-11-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Christian Reitwiessner</name><email>c@ethdev.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/5/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/5/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        

        
        <category
            term="tag:eip:5"
            label="EIP-5" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/5/">&lt;h3 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h3&gt;
&lt;p&gt;This EIP makes it possible to call functions that return strings and other dynamically-sized arrays.
Currently, when another contract &#x2F; function is called from inside the Ethereum Virtual Machine,
the size of the output has to be specified in advance. It is of course possible to give a larger
size, but gas also has to be paid for memory that is not written to, which makes returning
dynamically-sized data both costly and inflexible to the extent that it is actually unusable.&lt;&#x2F;p&gt;
&lt;p&gt;The solution proposed in this EIP is to charge gas only for memory that is actually written to at
the time the &lt;code&gt;CALL&lt;&#x2F;code&gt; returns.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;The gas and memory semantics for &lt;code&gt;CALL&lt;&#x2F;code&gt;, &lt;code&gt;CALLCODE&lt;&#x2F;code&gt; and &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; (called later as &lt;code&gt;CALL*&lt;&#x2F;code&gt;)
are changed in the following way (&lt;code&gt;CREATE&lt;&#x2F;code&gt; does not write to memory and is thus unaffected):&lt;&#x2F;p&gt;
&lt;p&gt;Suppose the arguments to &lt;code&gt;CALL*&lt;&#x2F;code&gt; are &lt;code&gt;gas, address, value, input_start, input_size, output_start, output_size&lt;&#x2F;code&gt;,
then, at the beginning of the opcode, gas for growing memory is only charged for &lt;code&gt;input_start + input_size&lt;&#x2F;code&gt;, but not
for &lt;code&gt;output_start + output_size&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If the called contract returns data of size &lt;code&gt;n&lt;&#x2F;code&gt;, the memory of the calling contract is grown to
&lt;code&gt;output_start + min(output_size, n)&lt;&#x2F;code&gt; (and the calling contract is charged gas for that) and the
output is written to the area &lt;code&gt;[output_start, output_start + min(n, output_size))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The calling contract can run out of gas both at the beginning of the opcode and at the end
of the opcode.&lt;&#x2F;p&gt;
&lt;p&gt;After the call, the &lt;code&gt;MSIZE&lt;&#x2F;code&gt; opcode should return the size the memory was actually grown to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h3&gt;
&lt;p&gt;In general, it is good practice to reserve a certain memory area for the output of a call,
because letting a subroutine write to arbitrary areas in memory might be dangerous. On the
other hand, it is often hard to know the output size of a call prior to performing the call:
The data could be in the storage of another contract which is generally inaccessible and
determining its size would require another call to that contract.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, charging gas for areas of memory that are not actually written to is unnecessary.&lt;&#x2F;p&gt;
&lt;p&gt;This proposal tries to solve both problems: A caller can choose to provide a gigantic area of
memory at the end of their memory area. The callee can &quot;write&quot; to it by returning and the
caller is only charged for the memory area that is actually written.&lt;&#x2F;p&gt;
&lt;p&gt;This makes it possible to return dynamic data like strings and dynamically-sized arrays
in a very flexible way. It is even possible to determine the size of the returned data:
If the caller uses &lt;code&gt;output_start = MSIZE&lt;&#x2F;code&gt; and &lt;code&gt;output_size = 2**256-1&lt;&#x2F;code&gt;, the area of
memory that was actually written to is &lt;code&gt;(output_start, MSIZE)&lt;&#x2F;code&gt; (here, &lt;code&gt;MSIZE&lt;&#x2F;code&gt; as evaluated
after the call). This is important because it allows &quot;proxy&quot; contracts
which call other contracts whose interface they do not know and just return their output,
i.e. they both forward the input and the output. For this, it is important that the caller
(1) does not need to know the size of the output in advance and (2) can determine the
size of the output after the call.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;This way of dealing with the problem requires a minimal change to the Ethereum Virtual Machine.
Other means of achieving a similar goal would have changed the opcodes themselves or
the number of their arguments. Another possibility would have been to only change the
gas mechanics if &lt;code&gt;output_size&lt;&#x2F;code&gt; is equal to &lt;code&gt;2**256-1&lt;&#x2F;code&gt;. Since the main difficulty in the
implementation is that memory has to be enlarged at two points in the code around &lt;code&gt;CALL&lt;&#x2F;code&gt;,
this would not have been a simplification.&lt;&#x2F;p&gt;
&lt;p&gt;At an earlier stage, it was proposed to also add the size of the returned data on the stack,
but the &lt;code&gt;MSIZE&lt;&#x2F;code&gt; mechanism described above should be sufficient and is much better
backwards compatible.&lt;&#x2F;p&gt;
&lt;p&gt;Some comments are available at https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;8&lt;&#x2F;p&gt;
&lt;h3 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;This proposal changes the semantics of contracts because contracts can access the gas counter
and the size of memory.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, it is unlikely that existing contracts will suffer from this change due to
the following reasons:&lt;&#x2F;p&gt;
&lt;p&gt;Gas:&lt;&#x2F;p&gt;
&lt;p&gt;The VM will not charge more gas than before. Usually, contracts are written in a way such
that their semantics do not change if they use up less gas. If more gas were used, contracts
might go out-of-gas if they perform a tight estimation for gas needed by sub-calls. Here,
contracts might only return more gas to their callers.&lt;&#x2F;p&gt;
&lt;p&gt;Memory size:&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;MSIZE&lt;&#x2F;code&gt; opcode is typically used to allocate memory at a previously unused spot.
The change in semantics affects existing contracts in two ways:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Overlaps in allocated memory. By using &lt;code&gt;CALL&lt;&#x2F;code&gt;, a contract might have wanted to allocate
a certain slice of memory, even if that is not written to by the called contract.
Subsequent uses of &lt;code&gt;MSIZE&lt;&#x2F;code&gt; to allocate memory might overlap with this slice that is
now smaller than before the change. It is, though, unlikely that such contracts exist.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Memory addresses change. Rather general, if memory is allocated using &lt;code&gt;MSIZE&lt;&#x2F;code&gt;, the
addresses of objects in memory will be different after the change. Contracts should
all be written in a way, though, such that objects in memory are &lt;em&gt;relocatable&lt;&#x2F;em&gt;,
i.e. their absolute position in memory and their relative position to other
objects does not matter. This is of course not the case for arrays, but they
are allocated in a single allocation and not with an intermediate &lt;code&gt;CALL&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;VM implementers should take care not to grow the memory until the end of the call and after a check that sufficient
gas is still available. Typical uses of the EIP include &quot;reserving&quot; &lt;code&gt;2**256-1&lt;&#x2F;code&gt; bytes of memory for the output.&lt;&#x2F;p&gt;
&lt;p&gt;Python implementation:&lt;&#x2F;p&gt;
&lt;p&gt;old: http:&#x2F;&#x2F;vitalik.ca&#x2F;files&#x2F;old.py
new: http:&#x2F;&#x2F;vitalik.ca&#x2F;files&#x2F;new.py&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Renaming SUICIDE opcode</title>
        <published>2015-11-22T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Hudson Jameson</name><email>hudson@hudsonjameson.com</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/6/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/6/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="interface"
                label="Interface" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:6"
            label="EIP-6" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/6/">&lt;h3 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h3&gt;
&lt;p&gt;The solution proposed in this EIP is to change the name of the &lt;code&gt;SUICIDE&lt;&#x2F;code&gt; opcode in Ethereum programming languages with &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h3&gt;
&lt;p&gt;Mental health is a very real issue for many people and small notions can make a difference. Those dealing with loss or depression would benefit from not seeing the word suicide in our programming languages. By some estimates, 350 million people worldwide suffer from depression. The semantics of Ethereum&#x27;s programming languages need to be reviewed often if we wish to grow our ecosystem to all types of developers.&lt;&#x2F;p&gt;
&lt;p&gt;An Ethereum security audit commissioned by DEVolution, GmbH and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LeastAuthority&#x2F;ethereum-analyses&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;performed by Least Authority&lt;&#x2F;a&gt; recommended the following:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Replace the instruction name &quot;suicide&quot; with a less connotative word like &quot;self-destruct&quot;, &quot;destroy&quot;, &quot;terminate&quot;, or &quot;close&quot;, especially since that is a term describing the natural conclusion of a contract.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The primary reason for us to change the term suicide is to show that people matter more than code and Ethereum is a mature enough of a project to recognize the need for a change. Suicide is a heavy subject and we should make every effort possible to not affect those in our development community who suffer from depression or who have recently lost someone to suicide. Ethereum is a young platform and it will cause less headaches if we implement this change early on in its life.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; is added as an alias of &lt;code&gt;SUICIDE&lt;&#x2F;code&gt; opcode (rather than replacing it).
https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;solidity&#x2F;commit&#x2F;a8736b7b271dac117f15164cf4d2dfabcdd2c6fd
https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;serpent&#x2F;commit&#x2F;1106c3bdc8f1bd9ded58a452681788ff2e03ee7c&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Token Standard</title>
        <published>2015-11-19T00:00:00+00:00</published>
        <updated>2026-02-11T14:48:25+00:00</updated>
	
	
	<author>
		<name>Fabian Vogelsteller</name><email>fabian@ethereum.org</email>
	</author>
	
	<author>
		<name>Vitalik Buterin</name><email>vitalik.buterin@ethereum.org</email>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/20/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/20/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="erc"
                label="ERC" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:20"
            label="ERC-20" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/20/">&lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface for tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h2&gt;
&lt;p&gt;The following standard allows for the implementation of a standard API for tokens within smart contracts.
This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;token&quot;&gt;Token&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;NOTES&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The following specifications use syntax from Solidity &lt;code&gt;0.4.17&lt;&#x2F;code&gt; (or above)&lt;&#x2F;li&gt;
&lt;li&gt;Callers MUST handle &lt;code&gt;false&lt;&#x2F;code&gt; from &lt;code&gt;returns (bool success)&lt;&#x2F;code&gt;.  Callers MUST NOT assume that &lt;code&gt;false&lt;&#x2F;code&gt; is never returned!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;name&quot;&gt;name&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the name of the token - e.g. &lt;code&gt;&quot;MyToken&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability,
but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;symbol&quot;&gt;symbol&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the symbol of the token. E.g. &quot;HIX&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability,
but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;decimals&quot;&gt;decimals&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the number of decimals the token uses - e.g. &lt;code&gt;8&lt;&#x2F;code&gt;, means to divide the token amount by &lt;code&gt;100000000&lt;&#x2F;code&gt; to get its user representation.&lt;&#x2F;p&gt;
&lt;p&gt;OPTIONAL - This method can be used to improve usability,
but interfaces and other contracts MUST NOT expect these values to be present.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; decimals&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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;h4 id=&quot;totalsupply&quot;&gt;totalSupply&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the total token supply.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&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;h4 id=&quot;balanceof&quot;&gt;balanceOf&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the account balance of another account with address &lt;code&gt;_owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; balance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transfer&quot;&gt;transfer&lt;&#x2F;h4&gt;
&lt;p&gt;Transfers &lt;code&gt;_value&lt;&#x2F;code&gt; amount of tokens to address &lt;code&gt;_to&lt;&#x2F;code&gt;, and MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.
The function SHOULD &lt;code&gt;throw&lt;&#x2F;code&gt; if the message caller&#x27;s account balance does not have enough tokens to spend.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt; Transfers of 0 values MUST be treated as normal transfers and fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;transferfrom&quot;&gt;transferFrom&lt;&#x2F;h4&gt;
&lt;p&gt;Transfers &lt;code&gt;_value&lt;&#x2F;code&gt; amount of tokens from address &lt;code&gt;_from&lt;&#x2F;code&gt; to address &lt;code&gt;_to&lt;&#x2F;code&gt;, and MUST fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;transferFrom&lt;&#x2F;code&gt; method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf.
This can be used for example to allow a contract to transfer tokens on your behalf and&#x2F;or to charge fees in sub-currencies.
The function SHOULD &lt;code&gt;throw&lt;&#x2F;code&gt; unless the &lt;code&gt;_from&lt;&#x2F;code&gt; account has deliberately authorized the sender of the message via some mechanism.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt; Transfers of 0 values MUST be treated as normal transfers and fire the &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;approve&quot;&gt;approve&lt;&#x2F;h4&gt;
&lt;p&gt;Allows &lt;code&gt;_spender&lt;&#x2F;code&gt; to withdraw from your account multiple times, up to the &lt;code&gt;_value&lt;&#x2F;code&gt; amount. If this function is called again it overwrites the current allowance with &lt;code&gt;_value&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;&#x2F;strong&gt;: To prevent attack vectors like the one &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM&#x2F;&quot;&gt;described here&lt;&#x2F;a&gt; and discussed &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;20#issuecomment-263524729&quot;&gt;here&lt;&#x2F;a&gt;,
clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to &lt;code&gt;0&lt;&#x2F;code&gt; before setting it to another value for the same spender.
THOUGH The contract itself shouldn&#x27;t enforce it, to allow backwards compatibility with contracts deployed before&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; success&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;allowance&quot;&gt;allowance&lt;&#x2F;h4&gt;
&lt;p&gt;Returns the amount which &lt;code&gt;_spender&lt;&#x2F;code&gt; is still allowed to withdraw from &lt;code&gt;_owner&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; public&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; view&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; remaining&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;events&quot;&gt;Events&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;transfer-1&quot;&gt;Transfer&lt;&#x2F;h4&gt;
&lt;p&gt;MUST trigger when tokens are transferred, including zero value transfers.&lt;&#x2F;p&gt;
&lt;p&gt;A token contract which creates new tokens SHOULD trigger a Transfer event with the &lt;code&gt;_from&lt;&#x2F;code&gt; address set to &lt;code&gt;0x0&lt;&#x2F;code&gt; when tokens are created.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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;h4 id=&quot;approval&quot;&gt;Approval&lt;&#x2F;h4&gt;
&lt;p&gt;MUST trigger on any successful call to &lt;code&gt;approve(address _spender, uint256 _value)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; address&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; _spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&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;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;There are already plenty of ERC20-compliant tokens deployed on the Ethereum network.
Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;example-implementations-are-available-at&quot;&gt;Example implementations are available at&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;.&#x2F;assets&#x2F;OpenZeppelin-ERC20.sol&quot;&gt;OpenZeppelin implementation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;20&#x2F;.&#x2F;assets&#x2F;Consensys-EIP20.sol&quot;&gt;ConsenSys implementation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;history&quot;&gt;History&lt;&#x2F;h2&gt;
&lt;p&gt;Historical links related to this standard:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Original proposal from Vitalik Buterin: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Standardized_Contract_APIs&#x2F;499c882f3ec123537fc2fccd57eaa29e6032fe4a&lt;&#x2F;li&gt;
&lt;li&gt;Reddit discussion: https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;ethereum&#x2F;comments&#x2F;3n8fkn&#x2F;lets_talk_about_the_coin_standard&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;Original Issue #20: https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;issues&#x2F;20&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;&#x2F;h2&gt;
&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;license&#x2F;&quot;&gt;CC0&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>EIP Classification</title>
        <published>2015-11-17T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Joseph Chow</name><uri>https://github.com/ethers</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/4/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/4/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="meta"
                label="Meta" />
            
        

        
        <category
            term="tag:eip:4"
            label="EIP-4" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/4/">&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;&#x2F;h1&gt;
&lt;p&gt;This document describes a classification scheme for EIPs, adapted from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;master&#x2F;bip-0123.mediawiki&quot;&gt;BIP 123&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;EIPs are classified by system layers with lower numbered layers involving more intricate interoperability requirements.&lt;&#x2F;p&gt;
&lt;p&gt;The specification defines the layers and sets forth specific criteria for deciding to which layer a particular standards EIP belongs.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h1&gt;
&lt;p&gt;Ethereum is a system involving a number of different standards. Some standards are absolute requirements for interoperability while others can be considered optional, giving implementers a choice of whether to support them.&lt;&#x2F;p&gt;
&lt;p&gt;In order to have a EIP process which more closely reflects the interoperability requirements, it is necessary to categorize EIPs accordingly. Lower layers present considerably greater challenges in getting standards accepted and deployed.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;Standards EIPs are placed in one of four layers:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Consensus&lt;&#x2F;li&gt;
&lt;li&gt;Networking&lt;&#x2F;li&gt;
&lt;li&gt;API&#x2F;RPC&lt;&#x2F;li&gt;
&lt;li&gt;Applications&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;1-consensus-layer&quot;&gt;1. Consensus Layer&lt;&#x2F;h1&gt;
&lt;p&gt;The consensus layer defines cryptographic commitment structures. Its purpose is ensuring that anyone can locally evaluate whether a particular state and history is valid, providing settlement guarantees, and assuring eventual convergence.&lt;&#x2F;p&gt;
&lt;p&gt;The consensus layer is not concerned with how messages are propagated on a network.&lt;&#x2F;p&gt;
&lt;p&gt;Disagreements over the consensus layer can result in network partitioning, or forks, where different nodes might end up accepting different incompatible histories. We further subdivide consensus layer changes into soft forks and hard forks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;soft-forks&quot;&gt;Soft Forks&lt;&#x2F;h2&gt;
&lt;p&gt;In a soft fork, some structures that were valid under the old rules are no longer valid under the new rules. Structures that were invalid under the old rules continue to be invalid under the new rules.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hard-forks&quot;&gt;Hard Forks&lt;&#x2F;h2&gt;
&lt;p&gt;In a hard fork, structures that were invalid under the old rules become valid under the new rules.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;2-networking-layer&quot;&gt;2. Networking Layer&lt;&#x2F;h1&gt;
&lt;p&gt;The networking layer specifies the Ethereum wire protocol (eth) and the Light Ethereum Subprotocol (les). RLPx is excluded and tracked in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;devp2p&quot;&gt;devp2p repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Only a subset of subprotocols are required for basic node interoperability. Nodes can support further optional extensions.&lt;&#x2F;p&gt;
&lt;p&gt;It is always possible to add new subprotocols without breaking compatibility with existing protocols, then gradually deprecate older protocols. In this manner, the entire network can be upgraded without serious risks of service disruption.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;3-api-rpc-layer&quot;&gt;3. API&#x2F;RPC Layer&lt;&#x2F;h1&gt;
&lt;p&gt;The API&#x2F;RPC layer specifies higher level calls accessible to applications. Support for these EIPs is not required for basic network interoperability but might be expected by some client applications.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s room at this layer to allow for competing standards without breaking basic network interoperability.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;4-applications-layer&quot;&gt;4. Applications Layer&lt;&#x2F;h1&gt;
&lt;p&gt;The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Homestead Hard-fork Changes</title>
        <published>2015-11-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/2/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/2/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        

        
        <category
            term="tag:eip:2"
            label="EIP-2" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/2/">&lt;h3 id=&quot;meta-reference&quot;&gt;Meta reference&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;606&#x2F;&quot;&gt;Homestead&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;FORK_BLKNUM&lt;&#x2F;th&gt;&lt;th&gt;CHAIN_NAME&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1,150,000&lt;&#x2F;td&gt;&lt;td&gt;Main net&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;494,000&lt;&#x2F;td&gt;&lt;td&gt;Morden&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;Future testnets&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h1 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h1&gt;
&lt;p&gt;If &lt;code&gt;block.number &amp;gt;= HOMESTEAD_FORK_BLKNUM&lt;&#x2F;code&gt;, do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The gas cost &lt;em&gt;for creating contracts via a transaction&lt;&#x2F;em&gt; is increased from 21,000 to 53,000, i.e. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53,000 plus the gas cost of the tx data, rather than 21,000 as is currently the case. Contract creation from a contract using the &lt;code&gt;CREATE&lt;&#x2F;code&gt; opcode is unaffected.&lt;&#x2F;li&gt;
&lt;li&gt;All transaction signatures whose s-value is greater than &lt;code&gt;secp256k1n&#x2F;2&lt;&#x2F;code&gt; are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values; this is useful e.g. if a contract recovers old Bitcoin signatures.&lt;&#x2F;li&gt;
&lt;li&gt;If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (i.e. goes out-of-gas) rather than leaving an empty contract.&lt;&#x2F;li&gt;
&lt;li&gt;Change the difficulty adjustment algorithm from the current formula: &lt;code&gt;block_diff = parent_diff + parent_diff &#x2F;&#x2F; 2048 * (1 if block_timestamp - parent_timestamp &amp;lt; 13 else -1) + int(2**((block.number &#x2F;&#x2F; 100000) - 2))&lt;&#x2F;code&gt; (where the &lt;code&gt;int(2**((block.number &#x2F;&#x2F; 100000) - 2))&lt;&#x2F;code&gt; represents the exponential difficulty adjustment component) to &lt;code&gt;block_diff = parent_diff + parent_diff &#x2F;&#x2F; 2048 * max(1 - (block_timestamp - parent_timestamp) &#x2F;&#x2F; 10, -99) + int(2**((block.number &#x2F;&#x2F; 100000) - 2))&lt;&#x2F;code&gt;, where &lt;code&gt;&#x2F;&#x2F;&lt;&#x2F;code&gt; is the integer division operator, eg. &lt;code&gt;6 &#x2F;&#x2F; 2 = 3&lt;&#x2F;code&gt;, &lt;code&gt;7 &#x2F;&#x2F; 2 = 3&lt;&#x2F;code&gt;, &lt;code&gt;8 &#x2F;&#x2F; 2 = 4&lt;&#x2F;code&gt;. The &lt;code&gt;minDifficulty&lt;&#x2F;code&gt; still defines the minimum difficulty allowed and no adjustment may take it below this.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h1&gt;
&lt;p&gt;Currently, there is an excess incentive to create contracts via transactions, where the cost is 21,000, rather than contracts, where the cost is 32,000. Additionally, with the help of suicide refunds, it is currently possible to make a simple ether value transfer using only 11,664 gas; the code for doing this is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; ethereum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; tester&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt; ethereum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; utils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;abi_contract&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;def init():&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; suicide(0x47e25df8822538a8596b28c637896b4d143c351e)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; endowment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_receipts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas_used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;11664&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_balance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;utils&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;normalize_address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;47e25df8822538a8596b28c637896b4d143c351e&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-constant&quot;&gt;1000000000000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is not a particularly serious problem, but it is nevertheless arguably a bug.&lt;&#x2F;p&gt;
&lt;p&gt;Allowing transactions with any s value with &lt;code&gt;0 &amp;lt; s &amp;lt; secp256k1n&lt;&#x2F;code&gt;, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from &lt;code&gt;s&lt;&#x2F;code&gt; to &lt;code&gt;secp256k1n - s&lt;&#x2F;code&gt;, flip the v value (&lt;code&gt;27 -&amp;gt; 28&lt;&#x2F;code&gt;, &lt;code&gt;28 -&amp;gt; 27&lt;&#x2F;code&gt;), and the resulting signature would still be valid. This is not a serious security flaw, especially since Ethereum uses addresses and not transaction hashes as the input to an ether value transfer or other transaction, but it nevertheless creates a UI inconvenience as an attacker can cause the transaction that gets confirmed in a block to have a different hash from the transaction that any user sends, interfering with user interfaces that use transaction hashes as tracking IDs. Preventing high s values removes this problem.&lt;&#x2F;p&gt;
&lt;p&gt;Making contract creation go out-of-gas if there is not enough gas to pay for the final gas fee has the benefits that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;(i) it creates a more intuitive &quot;success or fail&quot; distinction in the result of a contract creation process, rather than the current &quot;success, fail, or empty contract&quot; trichotomy;&lt;&#x2F;li&gt;
&lt;li&gt;(ii) makes failures more easily detectable, as unless contract creation fully succeeds then no contract account will be created at all; and&lt;&#x2F;li&gt;
&lt;li&gt;(iii) makes contract creation safer in the case where there is an endowment, as there is a guarantee that either the entire initiation process happens or the transaction fails and the endowment is refunded.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The difficulty adjustment change conclusively solves a problem that the Ethereum protocol saw two months ago where an excessive number of miners were mining blocks that contain a timestamp equal to &lt;code&gt;parent_timestamp + 1&lt;&#x2F;code&gt;; this skewed the block time distribution, and so the current block time algorithm, which targets a &lt;em&gt;median&lt;&#x2F;em&gt; of 13 seconds, continued to target the same median but the mean started increasing. If 51% of miners had started mining blocks in this way, the mean would have increased to infinity. The proposed new formula is roughly based on targeting the mean; one can prove that with the formula in use, an average block time longer than 24 seconds is mathematically impossible in the long term.&lt;&#x2F;p&gt;
&lt;p&gt;The use of &lt;code&gt;(block_timestamp - parent_timestamp) &#x2F;&#x2F; 10&lt;&#x2F;code&gt; as the main input variable rather than the time difference directly serves to maintain the coarse-grained nature of the algorithm, preventing an excessive incentive to set the timestamp difference to exactly 1 in order to create a block that has slightly higher difficulty and that will thus be guaranteed to beat out any possible forks. The cap of -99 simply serves to ensure that the difficulty does not fall extremely far if two blocks happen to be very far apart in time due to a client security bug or other black-swan issue.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h1&gt;
&lt;p&gt;This is implemented in Python here:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;blob&#x2F;d117c8f3fd93359fc641fd850fa799436f7c43b5&#x2F;ethereum&#x2F;processblock.py#L130&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;blob&#x2F;d117c8f3fd93359fc641fd850fa799436f7c43b5&#x2F;ethereum&#x2F;processblock.py#L129&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;blob&#x2F;d117c8f3fd93359fc641fd850fa799436f7c43b5&#x2F;ethereum&#x2F;processblock.py#L304&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;pyethereum&#x2F;blob&#x2F;d117c8f3fd93359fc641fd850fa799436f7c43b5&#x2F;ethereum&#x2F;blocks.py#L42&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>DELEGATECALL</title>
        <published>2015-11-15T00:00:00+00:00</published>
        <updated>2026-02-11T14:49:27+00:00</updated>
	
	
	<author>
		<name>Vitalik Buterin</name><uri>https://github.com/vbuterin</uri>
	</author>
	
	
        <link rel="alternate" href="https://wg-eips.ritovision.com/7/" type="text/html"/>
        

        <id>https://wg-eips.ritovision.com/7/</id>
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;type&#x2F;"
                term="standards-track"
                label="Standards Track" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;category&#x2F;"
                term="core"
                label="Core" />
            
        
            
            
            
            <category
                scheme="https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;status&#x2F;"
                term="final"
                label="Final" />
            
        

        
        <category
            term="tag:eip:7"
            label="EIP-7" />
        

        
        

        
        <content type="html"  xml:base="https://wg-eips.ritovision.com/7/">&lt;h3 id=&quot;hard-fork&quot;&gt;Hard Fork&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wg-eips.ritovision.com&#x2F;606&#x2F;&quot;&gt;Homestead&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters&quot;&gt;Parameters&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Activation:
&lt;ul&gt;
&lt;li&gt;Block &amp;gt;= 1,150,000 on Mainnet&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 494,000 on Morden&lt;&#x2F;li&gt;
&lt;li&gt;Block &amp;gt;= 0 on future testnets&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h3&gt;
&lt;p&gt;Add a new opcode, &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; at &lt;code&gt;0xf4&lt;&#x2F;code&gt;, which is similar in idea to &lt;code&gt;CALLCODE&lt;&#x2F;code&gt;, except that it propagates the sender and value from the parent scope to the child scope, i.e. the call created has the same sender and value as the original call.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specification&quot;&gt;Specification&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt;: &lt;code&gt;0xf4&lt;&#x2F;code&gt;, takes 6 operands:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gas&lt;&#x2F;code&gt;: the amount of gas the code may use in order to execute;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;to&lt;&#x2F;code&gt;: the destination address whose code is to be executed;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;in_offset&lt;&#x2F;code&gt;: the offset into memory of the input;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;in_size&lt;&#x2F;code&gt;: the size of the input in bytes;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;out_offset&lt;&#x2F;code&gt;: the offset into memory of the output;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;out_size&lt;&#x2F;code&gt;: the size of the scratch pad for the output.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;notes-on-gas&quot;&gt;Notes on gas&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The basic stipend is not given; &lt;code&gt;gas&lt;&#x2F;code&gt; is the total amount the callee receives.&lt;&#x2F;li&gt;
&lt;li&gt;Like &lt;code&gt;CALLCODE&lt;&#x2F;code&gt;, account creation never happens, so the upfront gas cost is always &lt;code&gt;schedule.callGas&lt;&#x2F;code&gt; + &lt;code&gt;gas&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Unused gas is refunded as normal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;notes-on-sender&quot;&gt;Notes on sender&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CALLER&lt;&#x2F;code&gt; and &lt;code&gt;VALUE&lt;&#x2F;code&gt; behave exactly in the callee&#x27;s environment as they do in the caller&#x27;s environment.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;other-notes&quot;&gt;Other notes&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The depth limit of 1024 is still preserved as normal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Propagating the sender and value from the parent scope to the child scope makes it much easier for a contract to store another address as a mutable source of code and &#x27;&#x27;pass through&#x27;&#x27; calls to it, as the child code would execute in essentially the same environment (except for reduced gas and increased callstack depth) as the parent.&lt;&#x2F;p&gt;
&lt;p&gt;Use case 1: split code to get around 3m gas barrier&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;253&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span&gt;delegate_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;ADDR1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;253&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span&gt;delegate_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;ADDR2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use case 2: mutable address for storing the code of a contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;224&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12345678&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&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 class=&quot;z-variable z-language&quot;&gt;    self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;delegate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldataload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&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 class=&quot;z-keyword&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 class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span&gt;delegate_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;gas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;delegate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    ~&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000&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 child functions called by these methods can now freely reference &lt;code&gt;msg.sender&lt;&#x2F;code&gt; and &lt;code&gt;msg.value&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;possible-arguments-against&quot;&gt;Possible arguments against&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;You can replicate this functionality by just sticking the sender into the first twenty bytes of the call data. However, this would mean that code would need to be specially compiled for delegated contracts, and would not be usable in delegated and raw contexts at the same time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
    </entry>
</feed>
